Этот API был определен, чтобы привести к одному знаменателю модули Python, которые используются, чтобы обратиться к базам данных. Этот документ описывает Python Database API 2.0. Спецификация интерфейса состоит из нескольких разделов:
Комментарии и вопросы относительно этой спецификации могут быть направлены на db-sig@python.org.
Для получения большего количества информации относительно связи с помощью
интерфейса базы данных с Python и о доступных пакетах изучите руководство на
http://www.python.org/topics/database.
5.7.1 Интерфейс модулей
Доступ к базе данных сделан доступным через объекты подключения. Модуль должен обеспечивать конструктор для них:
Эти глобальные переменные модуля должны быть определены:
'1.0'
и
'2.0'
. Если не задана, предполагается уровень
интерфейса Database API 1.0.
0 |
Потоки не могут совместно использовать модуль. |
1 |
Потоки могут совместно использовать модуль, но не подключения. |
2 |
Потоки могут совместно использовать модуль и подключения. |
3 |
Потоки могут совместно использовать модуль, курсоры и подключения. |
Совместное использование в вышеупомянутом контексте означает, что два потока могут использовать ресурс без того, чтобы применять mutex-семафор, чтобы выполнить блокировку ресурса. Обратите внимание, что Вы не можете всегда делать внешние ресурсы поточно-безопасными управляя доступом, использующим mutex: ресурс может полагаться на глобальные переменные или другие внешние источники данных, которые находятся вне Вашего управления!
'qmark' |
Стиль метки запроса, например, '...WHERE name=?' |
'numeric' |
Числовой, позиционный стиль, например, '...WHERE name=:1' |
'named' |
Именованный стиль, например, '...WHERE name=:name' |
'format' |
Формат кодов ANSI C printf, например, '...WHERE name=%s' |
'pyformat' |
Расширенные форматные коды языка Python, например, '...WHERE name=%(name)s' |
Модуль должен делать всю информацию об ошибках доступной через эти исключительные ситуации или через подклассы от них:
Если база данных не поддерживает функциональные возможности, требуемые методом, интерфейс должен породить исключительную ситуацию в случае, если метод используется.
Можно также не реализовывать метод вообще, тогда Python сам сгенерирует
исключительную ситуацию AttributeError
в случае, если метод
запрошен. Это позволяет программисту проверять возможности базы данных,
используя функцию hasattr()
.
Это размещение наследования исключительной ситуации:
StandardError |__Warning |__Error |__InterfaceError |__DatabaseError |__DataError |__OperationalError |__IntegrityError |__InternalError |__ProgrammingError |__NotSupportedError
Обратите внимание: значения этих исключительных ситуаций не определены.
Они должны дать пользователю информацию о том, что пошло не так.
5.7.2 Объекты подключения
Объекты подключения должны отвечать на следующие методы:
Error
(или подкласс от нее). То же самое
применяется ко всем объектам курсора, пробующим использовать подключение.
Модули баз данных, которые не поддерживают транзакции, должны выполнить этот метод с не имеющими силу функциональными возможностями.
Параметры конструктора подключения должны быть выполнены как параметры ключевого слова для более интуитивного использования и следовать этому порядку параметров:
dsn |
Источник данных как строка | обязательно |
user |
Имя пользователя как строка | опционально |
password |
Пароль пользователя как строка | опционально |
host |
Имя хоста | опционально |
database |
Имя базы данных | опционально |
Например, конструктор подключения мог бы выглядеть следующим образом:
connect(dsn='myhost:MYDB',user='guido',password='234+$')
.
5.7.3 Объекты курсоров
Эти объекты представляют курсор базы данных, который используется, чтобы управлять контекстом операции выборки.
Объекты курсоров должны отвечать на следующие методы и атрибуты:
(name, type_code, display_size,
internal_size, precision, scale, null_ok)
. Этот атрибут будет
None
для операций, которые не возвращают строки, или если курсор
не имел операции, вызываемой через метод executeXXX()
.
Код type_code
может интерпретироваться, сравнивая его с
Type Objects, определенными в разделе ниже.
executeXXX()
(для SQL-инструкций, вроде
select) или затронутых запросом (для SQL-инструкций, подобных
update или insert). Атрибут равен -1 в случае, если никакой
executeXXX()
не выполнился на курсоре.
fetchXXX()
.
Error
(или ее подкласс).
Ссылка на операцию будет сохраняться курсором. Если тот же самый объект операции передан снова, то курсор может оптимизировать поведение. Это наиболее эффективно для алгоритмов, где много раз используется та же самая операция, но с разными параметрами. Для достижения максимальной эффективности при многократном использовании операции, самое лучшее использовать метод setinputsizes(), чтобы определить типы параметра и размеры. Для параметра допустимо не соответствовать предопределенной информации: реализация должна это скомпенсировать, возможно, с потерей эффективности.
Параметры могут быть также определены как список, чтобы, например,
вставить много строк в одной операции, но этот вид использования не
рекомендуется: лучше пользуйтесь executemany()
.
seq_of_parameters
.
Модули могут выполнить этот метод, используя многократные обращения к
методу execute()
или используя операции массива, чтобы база
данных обработала всю последовательность в целом в одном обращении.
Те же самые комментарии, что касаются execute()
, также
применяются к этому методу. Значения возврата не определены.
None
, когда больше
нет доступных данных. Исключительная ситуация Error
(или ее
подкласс) произойдет, если предыдущее обращение к executeXXX()
не производило никакого набора результатов.
arraysize
курсора определяет число строк, которые будут
выбраны. Метод должен пробовать выбирать так много строк, как уаазано
параметром. Если это невозможно из-за определенного числа строк, меньшее
количество строк может быть возвращено.
Исключительная ситуация Error
(или ее подкласс) произойдет,
если предыдущее обращение к executeXXX()
не производило
никакого набора результатов.
Обратите внимание, что имеются сложности с эффективностью, включаемые с параметром размера. Для достижения оптимальной эффективности, обычно самое лучшее использовать arraysize.
Error
(или ее подкласс)
произойдет, если предыдущее обращение к executeXXX()
не
производило никакого набора результатов.
Этот метод будет переводить курсор к следующему доступному набору, отбрасывая любые остающиеся строки из текущего (актуального) набора.
Если не имеется больше никаких наборов, метод возвращает
None
. Иначе он возвращает значение true, и последующие обращения
к методам выборки возвратят строки из следующего набора результатов.
Исключительная ситуация Error
(или ее подкласс) произойдет,
если предыдущее обращение к executeXXX()
не производило
никакого набора результатов.
Обратите внимание, что интерфейс может выполнять выборку строки, используя массивы и другие оптимизацию. Не гарантируется, что обращение к этому методу только переместит связанный курсор вперед.
fetchmany()
за раз. Значение по умолчанию 1
(выбрать одиночную строку результатов)
Реализации должны отслеживать это значение применительно к методу
fetchmany()
, но никто не запрещает реально работать с базой
данных каким-либо иным способом. Это может также использоваться в
реализации метода executemany()
.
executeXXX()
к
предопределенным областям памяти для параметров операции. sizes
определен как последовательность: один элемент для каждого входного
параметра. Элемент должен быть Type Object, который соответствует вводу,
который будет использоваться, или это должно быть целым числом, определяющим
максимальную длину параметра строки. Если элемент равен None
, то
никакая предопределенная область памяти не будет зарезервирована для этого
столбца (это полезно, чтобы избегать предопределенных областей для больших
вводов). Метод не является обязательным для использования и реализации.
Многие базы данных должны иметь ввод в специфическом формате для
связывания с входными параметрами операции. Например, если ввод предназначен
для столбца DATE, то это будет связано с базой данных в специфическом формате
строки. Подобные проблемы существуют для столбцов "Row ID" или больших
двоичных элементов (например, столбцов blob или RAW). Это представляет
проблемы для Python, начиная с параметров для метода без контроля типов
executeXXX()
. Когда модуль базы данных видит строковый объект,
он не знает сходу, как с ним быть.
Чтобы преодолеть эту проблему, модуль должен обеспечить конструкторы, определенные ниже, чтобы создать объекты, которые могут хранить специальные значения. При передаче к методам курсора, модуль может затем обнаружить соответствующий тип входного параметра и обработать его соответственно.
Атрибут description
объекта курсора возвращает информацию
относительно каждого из столбцов результата запроса. Здесь
type_code
должен быть равен одному из Type Objects,
определенных ниже. Эти самые Type Objects могут быть равны больше, чем одному
коду типа (например, DATETIME может быть равен кодам типа для столбцов даты,
времени и метки времени).
Модуль экспортирует следующие конструкторы:
SQL-значение NULL представляется на вводе и выводе
как Python None
.
Обратите внимание: использование Unix-импульсов сигнала времени для связи
с помощью интерфейса базы данных может вызвать проблемы из-за ограниченного
диапазона даты, который они покрывают.
5.7.5 Хитрости в реализации
import time def DateFromTicks(ticks): return apply(Date,time.localtime(ticks)[:3]) def TimeFromTicks(ticks): return apply(Time,time.localtime(ticks)[3:6]) def TimestampFromTicks(ticks): return apply(Timestamp,time.localtime(ticks)[:6])
class DBAPITypeObject: def __init__(self,*values): self.values = values def __cmp__(self,other): if other in self.values: return 0 if other < self.values: return 1 else: return -1Возникающий в результате объект сравнивается со всеми значениями, переданными конструктору.
import exceptions class Error(exceptions.StandardError): pass class Warning(exceptions.StandardError): pass class InterfaceError(Error): pass class DatabaseError(Error): pass class InternalError(DatabaseError): pass class OperationalError(DatabaseError): pass class ProgrammingError(DatabaseError): pass class IntegrityError(DatabaseError): pass class DataError(DatabaseError): pass class NotSupportedError(DatabaseError): passНа C Вы можете использовать API
PyErr_NewException(fullname,base,NULL)
, чтобы создать
объекты исключительной ситуации.Python Database API 2.0 представляет несколько важных нововведений по сравнению с версией 1.0. Некоторые из этих изменений делают невозможным применять старые скрипты с новой версией DB API.
Хотя спецификация версии 2.0 разъясняет много вопросов, которые были оставлены открытыми в версии 1.0, некоторые все еще остаются проблемами:
Интерфейс базы данных может поддерживать именованные курсоры, позволяя
задавать методу параметр-строку. Это свойство пока не является частью
спецификации, так как оно сильно усложняет
семантику методов fetchXXX()
.
Модуль использует метод __getitem__
объекта параметров, чтобы
отобразить позиции (целые числа) или имена (строки) к значениям параметра.
Это учитывает последовательности и отображения, которые нужно
использовать как ввод.
Значение передается базе данных напрямую. В практических условиях это означает, что входное значение непосредственно используется как значение в операции. Пользователь не должен требоваться, чтобы экранировать значение так, чтобы оно могло использоваться: значение должно быть равно фактическому параметру для базы данных.
Атрибут rowcount
может быть реализован так, что модифицирует
значение динамически. Это может быть полезно для баз данных, которые
возвращают используемые значения rowcount
только после первого
обращения к методу fetchXXX()
.