Python Database API Specification v2.0
 
Этот перевод Python Database API Specification v2.0,
выполнен Михаилом Казаряном. Особая благодарность Олегу Бройтману.
Все предложения и замечания относительно перевода прошу присылать 
на mksendings[gav]ua[dot]fm.


Спецификация API СУБД для Python 2.0



Этот API был определен, чтобы способствовать единообразию между модулями Python, которые 
используются для обращения к СУБД. Делая это, мы надеемся достигнуть согласованности, 
ведущей к упрощению понятия кода модулей, который будет более переносным между 
различными СУБД и обеспечивать более широкую связь с базами данных из Python.

Спецификация интерфейса состоит из нескольких разделов:

* Интерфейсы модулей
* Cоединения
* Курсоры
* Типы и конструкторы
* Примеры реализации
* Основные изменения с 1.0 до 2.0

Комментарии и вопросы, касающиеся этой спецификации могут быть направлены 
SIG for Database Interfacing with Python. Для подробной информации относительно соединения с 
помощью интерфейса баз данных из Python и о доступных пакетах см. на www.python.org. Этот 
документ описывает API баз данных для Python, версии 2.0.  Предыдущая версия версии 1.0 все
еще доступна как справочник. Авторы пакетов поощряют использовать эту версию спецификации 
как основание для новых интерфейсов.

Интерфейсы модулей

Обращение к базе данных, доступно через соединения [1]. Модуль
должен предоставлять следующую конструкцию для этого:

connect(параметры...)
Конструктор для подключения к базе данных. Возвращает соединение. 
Получает количество параметров, зависящих от базы данных. [1]

Глобальные переменные модуля, которые должны быть определены:

apilevel
Строковая константа, определяющая поддерживаемый уровень API. В 
настоящее время допустимы только строки '1.0' и '2.0' . По 
умолчанию принимается API версии 1.0.

threadsafety
Целочисленная константа, устанавливающая уровень безопасности потока поддержки
интерфейса. Возможные значения:
0 = Потоки не могут совместно использовать модуль.
1 = Потоки могут совместно использовать модуль, но не подключения.
2 = Потоки могут совместно использовать модуль и подключения.
3 = Потоки могут совместно использовать модуль, подключения и курсоры.

Совместное использование в вышеупомянутом контексте означает, что два потока могут

использовать ресурс без использования семафоров, чтобы осуществить блокировку ресурса.
Обратите внимание, что вы не всегда можете создавать защищенный внешний ресурсный
поток, управляя доступом, используя взаимное исключение: ресурс может зависеть от
глобальных переменных или других внешних источников, которыми вы не управляете.

paramstyle
Строковая константа, устанавливающая тип форматирования маркера параметра, ожидаемого
интерфейсом. Возможные значения - [2]:
'qmark' = стиль ╚вопросительного знака╩, например '...WHERE name=? '
'numeric ' = Числовой, позиционный стиль, например '...WHERE name=:1'
'named ' = Именованный стиль, например '...WHERE name=:name '
'format ' = формат в стиле команды ANSI C printf , например '...WHERE name=%s'
'pyformat' = Расширения формата кода в стиле Python, например '...WHERE name=%(name)s'

Модуль должен делать доступными все сведения об ошибках через эти исключения или
их подклассы:

Warning
Исключение вызываемое для важных предупреждений подобно транзакциям при вставке данных
и т.д. Это должен быть подкласс Python StandardError (определенный в модуле exceptions).

Error
Исключение, которое является базовым классом для всех других исключений ошибок. Вы можете
использовать его для перехвата всех ошибок единственной инструкцией except. Предупреждения
(Warning) не считаются ошибками и поэтому не нужно использовать этот класс как базовый.
Это должен быть подкласс Python StandardError (определенный в исключениях модуля).

InterfaceError
Исключение вызываемое для ошибок, которые связаны с интерфейсом базы данных, а не базой
данных непосредственно. Это должен быть подкласс Error.

DatabaseError
Исключение вызываемое для ошибок, которые связаны с базой данных. Это должен быть 
подкласс Error.

DataError
Исключение вызываемое для ошибок, которые происходят из-за проблем с обработанными 
данными подобно делению на нуль, числовое значение вне диапазона, и т.д. Это должен быть 
подкласс DatabaseError.

OperationalError
Исключение вызываемое для ошибок, которые связаны с операцией в базе данных и не 
обязательно по вине программиста, например неожиданный разрыв соединения (дисконнект) 
происходит когда имя источника данных не найдено, не прошла транзакция, произошла ошибка 
распределения памяти в течение обработки, и т.д. Это должен быть подкласс DatabaseError.

IntegrityError
Исключение возникает, когда нарушается реляционная(ссылочная) целостность базы данных,
например, сбои при проверке внешнего ключа. Это должен быть подкласс DatabaseError.

InternalError
Исключение возникает, когда в базе данных возникает внутренняя ошибка, например курсор 
болеене доступен, транзакция - не синхронизирована, и т.д. Это должен быть подкласс DatabaseError.

ProgrammingError
Исключение возникает при ошибках программирования, например таблица, не найдена или уже
существует, синтаксическая ошибка в SQL-запросе, неправильно указанны параметры, и т.д. Это
должен быть подкласс DatabaseError.

NotSupportedError
Исключение вызывается в случае, если использовались метод или API, которые не 
поддерживается СУБД, например вызыв rollback() на соединении, которое не поддерживает 
транзакций. Это должен быть подкласс DatabaseError.

Дерево наследования исключений:

StandardError
|__Warning
|__Error
|__InterfaceError
|__DatabaseError
|__DataError
|__OperationalError
|__IntegrityError
|__InternalError
|__ProgrammingError
|__NotSupportedError

Обратите внимание: значения этих исключений не определены. Они должны дать 
пользователю хорошие идеи, относительно того, что пошло не так, как надо.

Соединения

Соединения должны включать следующие методы:

close()
Закрывает соединение сейчас (а не при вызове __del__). После этого соединение будет закрыто 
и будет сгенерировано исключение Error (или подкласс), если будет предпринята любая 
операция в рамках этого соединения. То же самое применимо ко всем курсорам, которые
используют это соединение.

commit()
Фиксирует любую неподтвержденную транзакцию в базе данных. Обратите внимание, что, 
если СУБД поддерживает автоподтверждение (auto-commit), commit должен быть изначально 
отключен. Метод интерфейса может быть предусмотрен, чтобы возвратить его. Модули СУБД, 
которые не поддерживают транзакции, должны включать этот метод с пустой 
функциональностью.

rollback()
Этот метод является дополнительным поскольку не все СУБД поддерживаю транзакции. [3]
В случае, если СУБД действительно поддерживает транзакции, этот метод заставляет СУБД
производить откат назад, к началу любой неподтвержденной транзакции. Закрытие соединения,
без подтверждения изменений (commit()) по умолчанию вызовет rollback().

cursor()
Возвращает новый курсор используя соединение. Если СУБД не поддерживает концепцию 
курсоров непосредственно, модуль должен будет эмулировать использование курсоров, 
используя другие средства до степени, требуемой этой спецификацией. [4]

Курсоры

Эти объекты представляют курсор базы данных, который используется для управления 
контекстом выборки.

Курсоры должны содержать следующие методы и атрибуты:

description
Этот атрибут "только для чтения" √ последовательность из 7-ми элементов. Каждая
из этих последовательностей содержит информацию, описывающую один столбец результата:
(name, type_code, display_size, internal_size, precision, scale, null_ok).

Этот атрибут вернет None для операций, которые не возвращают строки или если курсор не 
вызвал операцию через метод executeXXX().

type_code может интерпретироваться, при сравнии с типами, указанными в разделе ниже.

Rowcount
Этот атрибут "только для чтения" определяет количество строк, которое выполнил последний
executeXXX() (подобно select для инструкций SQL) или воздействовал (для инструкций DML 
подобно обновлению (update ) или вставке (insert)).Атрибут будет равен -1 в случае, если 
executeXXX() не был выполнен в пределах курсора, или количество записей (rowcount) 
последней операции не определено в интерфейсе. [7]

callproc(procname[,parameters])
Этот метод является необязательным, поскольку не все СУБД обеспечивают выполнение 
хранимых процедур. [3]

Вызов хранимой процедуры из базы данных осуществляется по имени procname.
Последовательность параметров должна содержать по одному вхождению на каждый аргумент,
требуемый процедурой. Результат запроса возвращается как измененная копия входной
последовательности. In, Out и In/Out параметры - это входные, выхоные, и двусторонние
параметры. То есть используются только для передачи данных в процедуру, только для возврата
значения, и для одновременного входа и выхода соответственно.

Процедура также может обеспечить вывод результирующего набора. Тогда это должно быть 
сделано через стандартные методы fetchXXX().

close()
Закрывает соединение (предпочтительно всякий раз, когда вызывается __del__ ). После этого
соединение будет закрыто; будет сгенерированоисключение Error (или подкласс), если будет
предпринята любая операция в рамках этого соединения. То же самое применимо ко всем 
курсорам, использующим это соединение.

execute(operation[,parameters])
Подготавливает и выполняет операцию (запрос или команду). Параметры могут быть 
представлены как последовательность или отображение, и будут связаны с переменными в 
операции. Переменные определены в определениях примечании базы данных ( для 
подробностей см. атрибут модуля  paramstyle). [5]

Ссылка на операцию будет сохранена курсором. Если та же операция выполнится снова, то 
курсор может оптимизировать её поведение. Это наиболее эффективно для алгоритмов, где 
много раз используется одна и та же самая операция, но с другими параметрами.

Для максимальной эффективности при многократном использовании операции, лучше 
заблаговременно использовать метод setinputsizes() для определения типов параметра и размеров. 
Это допустимо для параметра, который не соответствует встроенной информации; реализация 
должна компенсировать это, даже с потерей эффективности.

Параметры могут также быть определены, как список из кортежей, чтобы, например, вставить
множество строк в единственную операцию, но вместо этого лучше использовать executemany().
Возвращаемые значения не определены.

executemany(operation,seq_of_parameters)
Подготавливает операцию (запрос или команду), и затем выполняет её для всех 
последовательностей параметров или отображений, найденных в последовательности 
seq_of_parameters.

Модули свободны осуществить этот метод, используя множественные запросы к методу execute()
или используя массивы операций, чтобы база данных обрабатывала целую последовательность
в одном запросе.

Те же самые комментарии, что касаются execute() , также применимы и к этому методу.
Возвращаемые значения не определены.

fetchone()
Выберает следующую строку из полученного набора, возвращая единственную 
последовательность, или None , когда данные больше не доступны. [6]

Если предыдущий запрос executeXXX() не вернул результирующего набора или не был 
передан вообще, вызывается исключение Error (или его подкласс).

fetchmany([size=cursor.arraysize])
Выбирает следующий набор строк, полученный в результате выполнения запроса, возвращая
последовательность последовательностей (например список кортежей). Пустая 
последовательность возвращается, когда запрос не вернул ни одной строки.

Количество строк для выборки из запроса определены параметром. Если он не получен, размер
массива (arraysize) курсора определяется как число строк, которые будут выбраны. Метод
пытается выбрать количество строк, обозначенных параметром размера. Если результирующий
набор меньше указанного количества будет возвращено меньшее количество строк. Если 
предыдущий запрос executeXXX() не вернул результирующего набора или не был передан 
вообще, вызывается исключение Error (или его подкласс).

Обратите внимание, что это соображения выполнения, включенные с параметром размера. Для
оптимального выполнения, обычно лучше всего использовать атрибут arraysize. Если параметр
размера используется, то лучше сохранить значение из одного fetchmany() запроса к следующему.

fetchall()
Выбирает все строки результата запроса, возвращая их как последовательность 
последовательностей (например список кортежей).
Обратите внимание, что атрибут arraysize курсора может повлиять на выполнение этой операции.

Если предыдущий запрос executeXXX() не вернул результирующего набора или не был передан
вообще, вызывается исключение Error (или его подкласс).

nextset()
Этот метод является дополнительным, так как не все СУБД поддерживают множественные 
результаты набора. [3]

Этот метод будет делать пропуск курсора до следующего доступного набора, отказываясь от
любых остающихся строк текущего набора.

Если значений больше нет , метод возвращает None. Иначе, он возвращает истинное значение,
и последующие вызовы методов выборки возвратят строки из следующего результата запроса.

Если предыдущий запрос executeXXX() не вернул результирующего набора или не был передан
вообще, вызывается исключение Error (или его подкласс).

arraysize
Этот атрибут для чтения - записи определяет число строк, выбираемых одновременно с 
fetchmany(). По умолчанию значение равно 1 и выбирает единственную строку за раз.

Во время реализации нужно контролировать это значение относительно fetchmany(), но свободно
единовременно взаимодействует с одной строкой. То же актуально при выполнении 
executemany().

setinputsizes(sizes)
может быть использован перед вызовом executeXXX(), для параметров операции со встроенными
областями памяти. Размеры определены как последовательность по-одному элементу на каждый
входной параметр. Элемент должен быть типом объекта, который соответствует вводу, который
будет использоваться, или это должно быть целое число, определяющее максимальную длину
строкового параметра. Если элемент None , то встроенная область памяти не будет
зарезервирована для этого поля (лучше избегать встроенных областей для большинства вводов).

Этот метод используйте перед вызовом метода executeXXX().

Реализации вольны реализовывать этот метод как не делающий ничего, и пользователи могут не
использовать его.

setoutputsize(size[,column])
Устанавливает размер буфера столбца при выбороках больших полей (например. LONGs,
BLOB, и т.д.). Столбец определен как индекс в результирующей последовательности. В
неопределенном столбце установится заданный по умолчанию размер для всех больших 
столбцов в курсоре.

Используйте этот метод перед вызовом executeXXX().

При реализации программы выполнение этого метода не дает ничего, и пользователи могут не
использовать его.

Типы и конструкторы

Во многих СУБД ввод должны быть в конкретном формате для связки с входными параметрами
операции. Например, если планируется ввод в поле типа DATE, то он должен быть передан в
базу данных в специальном строковом формате. Аналогичные проблемы существуют для полей
"Row ID" или больших бинарных полей (например BLOB или RAW-полей). Это создает 
проблемы для Python начиная с параметров для метода executeXXX(), выполняемого без 
контроля типов. Когда модуль базы данных видит Python-новский строковый объект он не знает 
простой ли это столбец типа CHAR, BINARY или как DATE.

Для решения этой проблемы, модуль должен обеспечить конструкторы, определенные ниже, 
чтобы создать объекты, которые могут хранить специальные значения. Когда значение передано
методам курсора, модуль может тогда обнаружить соответствующий тип входного параметра и 
связать его с соответствующим типом СУБД.

Атрибут описания курсора возвращает информацию о каждом столбце результата запроса. 
type_code должен сравнить эту информацию с одним из типов, определенных ниже. Типы могут 
быть равны больше чем одному типу кода (например. DATETIME может соответствовать типам 
DATE, TIME и TIMESTAMP полей; для подробностей см. ниже "Примеры реализации").

Модуль экспортирует следующие единичные объекты:

Date(year,month,day)
Эта функция создает объект, содержащий значение даты.

Time(hour,minute,second)
Эта функция создает объект, содержащий значение времени.

Timestamp(year,month,day,hour,minute,second)
Эта функция создает объект, содержащий значение времени.

DateFromTicks(ticks)
Эта функция создает объект, содержащий значение даты от заданной точки (количество
секунд с начала эпохи; для подробностей см. документацию стандартного модуля time Python).

TimeFromTicks(ticks)
Эта функция создает объект, содержащий значение времени от заданной точки (количество
секунд с начала эпохи; для подробностей см. документацию стандартного модуля time Python).

TimestampFromTicks(ticks)
Эта функция создает объект, содержащий значение времени от заданной точки (количество
секунд с начала эпохи; для подробностей см. документацию стандартного модуля time Python).

Binary(string)
Эта функция создает объект, содержащая двоичное строковое значение.

STRING
Этот тип используется, чтобы описать строковые поля в базе данных (например CHAR).

BINARY
Этот объект тип используется, для описания (длинныех) двоичных столбцов в базе
данных (например. LONG, ROW, BLOB объекты).

NUMBER
Этот тип используется, чтобы описать числовые поля в базе данных.

DATETIME
Этот тип используется, чтобы описать столбцы date/time в базе данных.

ROWID
Этот объект типа используется, чтобы описать поле "Row ID" в базе данных.

Значения NULL в SQL представлены в Python, как None на входе и выходе.

Обратите внимание: Использование Unix-времени для связи с СУБД может вызвать
проблемы из-за ограниченного диапазона даты, который оно охватывает.

Примеры реализации

Предпочтительные типы для объектов date/time, определенные в пакете mxDateTime, который
обеспечивает все необходимые конструкторы и методы на уровнн C и Python.

Предпочтительный тип для объектов Binary √ буферный тип, доступный в стандартном Python,
начиная с версии 1.5.2. (для подробностей см. документацию Python). Для информации об
интерфейсе C смотрите на Include/bufferobject.h и Objects/bufferobject.c в исходных кодах Python.

В этом примере показана реализация работы с Unix-временем, основанная на конструкторе для
даты/времени, передающем работу общим(универсальным) конструкторам:

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])

Этот класс Python позволяет выполнять вышеупомянутые типы даже при том, что описание типа
поля, приводит к множественным значения для типа:

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

Результирующий тип сравнивается со всеми значениям, известными конструктору.

Это отрывок кода Python, реализующий иерархию исключений, описанную выше:

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 Вы можете использовать PyErr_NewException(fullname, base, NULL) API, чтобы
создать исключения.

Дополнительные расширения DB API.

За время существования DB API 2.0, авторы модуля часто расширяли реализацию в
соответствии с данной спецификацией DB API. Для расширения совместимости и обеспечения
чистого обновления до возможных будущих версий спецификации, этот раздел определяет ряд
общих расширений к основной спецификации DB API 2.0.

Поскольку авторы модуля к СУБД могут не реализовать эти дополнительные атрибуты и методы
со всеми дополнительными характеристиками DB API то их использование вызовет AttributeError
или вызовет NotSupportedError в случае, когда их доступность может быть проверена только
во время выполнения.

Было предложено сделать использование этих расширений дополнительно видимыми 
программисту, передавая предупреждения (warnings) через систему предупреждений Python. 
Чтобы сделать эту характеристику полезной, предупреждения должны быть стандартизированы 
для того, чтобы можно было маскировать их. Эти стандартные сообщения упомянуты ниже как
"Warning message".

Атрибут курсора .rownumber
Этот атрибут "только для чтения" должен обеспечить текущий индекс курсора (нумерация
начинается с нуля) в результирующем наборе или None, если индекс не может быть определен.
Индекс может быть виден как индекс курсора в последовательности (результирующем наборе).
Следующая операция выборки выберет строку, индексированную .rownumber в этой
последовательности.

Warning: "DB-API extension cursor.rownumber used"

Атрибут подключения .Error, .ProgrammingError, и т.д.
Все классы исключений, определенные в стандарте DB API должны быть доступны как атрибуты
Connection (в дополнение к доступности на уровне модуля). Эти атрибуты упрощают обработку
ошибок в средах с мультиподключением.

Warning Message: "DB-API extension connection. used"

Атрибут курсора .connection
Это атрибут "только для чтения", который возвращает ссылку на объект Connection,
который создал курсор. Атрибут упрощает запись полиморфного кода в средах с
мультиподключением.

Warning Message: "DB-API extension cursor.connection used"

Метод курсора .scroll(value[,mode='relative'])
перемещает курсор в результирующем наборе к новой позиции согласно режиму.

Если режим 'relative' √ относительный (значение по умолчанию), значение берется как
смещение к текущей позиции в результирующем наборе, если установлено в 'absolute'
('абсолютный'), значение указывает абсолютную позицию.

В случае, если операция перемещения покинет результирующий набор будет вызван IndexError.
В этом случае, позиция курсора остаётся неопределенной (в идеале курсор должен был бы не
перемещатся вообще).

Обратите внимание: этот метод должен использовать родные перемещаемые курсоры, если они
доступны, или эмуляровать для однонаправленных курсоров. Метод может вызвать
NotSupportedErrors, сообщая о том, что данная операция не поддерживается СУБД
(например перемещение назад).

Warning Message: "DB-API extension cursor.scroll() used"

Атрибут курсора .messages
Это список Python, в который интерфейс добавляет кортежи (класс исключения, значение
исключения) со всеми сообщениями, которые интерфейс получает от основной СУБД для
этого курсора.

Список очищается всеми стандартными вызовами методов курсора (до выполнения вызова),
исключая вызовы .fetchXXX() автоматически, чтобы избежать чрезмерного использования памяти,
и может также быть очищен после выполнения "del cursor.messages[:]".

Все ошибки и предупреждения, сгенерированные СУБД помещаются в этот список, поэтому
проверка списка позволяет пользователю проверять корректность операций вызова методов.

Задача этого атрибута - устранить необходимость в предупреждениях (Warning exception),
которые часто вызывает проблемы (некоторые предупреждения в действительности носят только
информационный характер).

Warning Message: "DB-API extension cursor.messages used"

Атрибут подключения .messages
То же самое, что и cursor.messages за исключением того, что сообщения в списке
ориентированны на подключение.

Список очищаеется автоматически всеми стандартными вызовами методов подключения
(до выполнения запроса), чтобы избежать чрезмерного использования памяти и может быть
очищен после выполнения "del cursor.messages[:]".

Warning Message: "DB-API extension cursor.messages used"

Метод курсора .next ()
Возвращает следующую строку из текущего выполнного SQL-запроса, используя семантику,
аналогичную .fetchone(). Когда результирующий набор исчерпан , вЁзЁвается исключение
StopIteration начиная с Python 2.2 и выше. Предыдущие версии не имеют исключения
StopIteration и таким образом вместо этого метод должен вызвать IndexError.

Warning Message: "DB-API extension cursor.next() used"

Метод курсора .__iter__()
Возвращает self, чтобы сделать курсоры совместимыми с протоколом итераций.

Warning Message: "DB-API extension cursor.__iter__() used"

Атрибут курсора .lastrowid
Этот атрибут "только для чтения" обеспечивает rowid последней измененной записи
(большинство СУБД возвращает rowid только, когда выполнена единственная операция
INSERT). Если операция не установила rowid или если СУБД не поддерживает rowid, этот
атрибут должен установить None.

Семантика .lastrowid неопределена в случае, если последний выполняемый запрос
изменил больше чем одну строку, например используя INSERT с .executemany().

Warning Message: "DB-API extension cursor.lastrowid used"

Дополнительное расширение обработки ошибок

Основная спецификация DB API только вводит ряд исключений, которые могут быть вызваны,
чтобы сообщить об ошибках пользователю. В некоторых случаях, исключения могут быть 
слишком разрушительными для процесса выполнения программы или даже делать выполнение 
невозможным.

Для этих случаев и чтобы упростить обработку ошибок, имея дело с СУБД, авторы модуля 
доступа к СУБД могут решить осуществлять пользовательские способы определения 
обработчиков ошибок. Эта секция описывает стандартный способ определить эти обработчики 
ошибок.

Атрибут курсора/подключения .errorhandler
Атрибут для чтения/записи, который ссылается на обработчик ошибок для вызова в случае, если
встречено ошибочное условие.

Обработчик должен вызываться из Python и принимать следующие параметры:
errorhandler (connection, cursor, errorclass, errorvalue), где connection - ссылка
на соединение, которое обслуживает курсор; cursor ссылка на курсор (или None один в случае,
если ошибка не относится к курсору); errorclass √ класс ошибки, предписывает значение,
используюя errorvalue как аргумент конструкции.

Стандартный обработчик ошибок должен добавить сведения об ошибке в соответствующий 
атрибут  .messages (connection.messages или cursor.messages) и вызывать исключение, определенное
данными параметрами errorclass и errorvalue.

Если errorhandler не установлен (атрибут None), должна быть применена стандартная схема
обработки ошибок, определенная выше.

Warning Message: "DB-API extension .errorhandler used"

Курсоры должны наследовать .errorhandler, устанавливаемые из их подключения во время
создания курсора.

Часто задаваемые вопросы
 
Группа по интересам СУБД часто видит повторяющиеся вопросы по спецификации DB API. 
Этот раздел покрывает некоторые проблемы, иногда возникающие при работе со спецификацией.

Вопрос:

Как мне создать словарь из кортежей, возвращенных .fetchxxx ():

Ответ:

Доступно несколько инструментов, решающих эту задачу. Большинство из них использует
названия столбцов, определенных в атрибуте курсора .description как основание ключа в
строке словаря.

Заметте, что причина по которой спецификация DB API не расширяется чтобы также
поддерживать словарь, возвращаемый методами .fetchxxx () - то, что этот подход имеет
несколько недостатков:

* Некоторые СУБД не поддерживают регистро-зависимые названия полей или автоматически
преобразовывают все символы имени столбца в нижний или верхний регистр.

* Столбцы в результирующем наборе, которые сгенерированы запросом (например используя
функции SQL) не отображают названия столбцов таблицы и СУБД обычно генерируют названия 
для этих столбцов в зависимости от внутренних особенностей.

В результате доступ к столбцам через ключи словаря меняется в зависимости от СУБД и
делает написание портируемого кода невозможным.

Основные изменения с версии 1.0 до версии 2.0



В API баз данных Python 2.0 вводит несколько основных изменений отностельно версияи 1.0.
Поскольку некоторые из этих изменений ломают программы, написанные с учетом DB API 1.0,
главный номер версии был изменен, чтобы отразить эти изменения.

Это - самые важные изменения с 1.0 до 2.0:
* Необходимость в отдельном модуле dbi была устранена, и функциональные возможности
перенесены непосредственно в интерфейс модуля.

* Новые конструкторы и типы добавлены для значений даты/времени,RAW Type Object 
	были переименован в BINARY. Результат должен охватить все основные типы данных, 
	обычно 	найденные в современных СУБД.

* Новые константы (apilevel, threadlevel, paramstyle) и методы (executemany, nextset)
добавлены, чтобы обеспечить лучшую связь с СУБД.

* Семантика .callproc(), которая должна была вызывать, хранимые процедуры теперь ясно
определена.

* В определении .execute() возвращаемое значение изменилось. Раньше, возвращаемое
значение было основано на типе SQL-запроса (который жестко, чтобы осуществлял это)
теперь это неопределено; используйте более гибкий атрибут .rowcount вместо этого.
Модули могут возвратить значения в старом стиле, но они больше не поддерживаются
спецификацией и считаются зависимыми от интерфейса СУБД.

*Базовые исключения были включены в спецификацию. Разработчики модуля могут 
	расширить исключения, определенное в этой спецификации.

Нерешённые проблемы.

Хотя спецификация версии 2.0 разъясняет относительно большое количество вопросов,
которые остались открытыми в версии 1.0, есть все еще некоторые остались проблемы:
* Определить полезное возвращаемое значение для .nextset() для случая, когда доступен
новый резльтирующий набор
* Создать числовой тип для использования денежно-кредитного и десятичного формата
обмена без потерь.

Сноски

1. Как руководство, параметры конструктора соединения должны быть осуществлены как
ключевые слова для более интуитивного использования и следует этому порядку параметров:

dsn = Строка, указывающая источник данных.
user = Строка, указывающая имя пользователя (опционально)
password = Строка, содержащая пароль (опционально)
host = Hostname (optional)
database = Database name (optional)

Пример подключения может выглядеть следующим образом:
connect(dsn='myhost:MYDB',user='guido',password='234$?')

2. Создатели модуля должны предпочесть 'numeric', 'named' или 'pyformat' другим форматам,
потому что они предоставляют больше ясности и гибкости.

3. Если СУБД не поддерживает функциональные возможности, требуемые методом, интерфейс
должен генерировать исключение в случае, если метод используется. Предпочтительней вообще
не реализовывать метод; тогда Python сгенерирует AttributeError. Это позволяет программисту
проверять возможности СУБД, используя стандартную функцию hasattr().

Для некоторых динамически конфигурируемых интерфейсов это может не соответствовать
требованию динамического создания доступного метода. Тогда эти интерфейсы должны
вызвать NotSupportedError, для указания невозможности отката назад, когда метод вызван.

4. Интерфейс базы данных может решить поддерживать ли именованные курсоры, позволяя
строковый параметр в методе. Эта особенность - не часть спецификации, так как это усложняет
семантику .fetchXXX () методов.

5. Модуль может реализовать метод __getitem__ параметров объекта для метки позиции (integer)
или имени (string) в значениях параметра. Это учитывает и последовательности и распределения,
которые используются на входе.

Термин "связанный" относится к процессу связывания входного значения с буфером выполнения
СУБД. Практически это означает, что входное значение непосредственно используется как
значение в операции. Клиент не обязан квотировать значения так, чтобы его можно было
использовать - значение должно быть равно фактическому значению базы данных.

6. Заметте, что интерфейс может осуществить выборку записей, используя массивы и другую
оптимизаторы. Не гарантируется, что вызов к этих методов только продвинет курсор на
одну строку.

7. Атрибут rowcount может быть реализован таким образом, чтобы осуществлять динамическую
модификацию его значений. Это может быть полезно для СУБД, которые возвращают осмысленные
значения rowcount только после первого вызова метода .fetchXXX().