Для чего применяется метод nextset() объекта-курсора?
Что передается методу executemany() объекта-курсора вторым параметром (дайте наиболее подходящий ответ)?
Что делает метод normalize() DOM-объекта?
В каких точках программы необходимо выполнять acquire() и release() замка Z , чтобы функция f могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x, y, z): global d # 1 d[(x, y)] = z # 2 res = len(d) # 3 return res
В каких точках программы необходимо выполнять acquire() и release() замка Z , чтобы функция f могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x, y, z): global d1, d2 # 1 d1[(x, y)] = z # 2 d2[z] = (x, y) # 3 res = len(d2) # 4 return res
В каких точках программы необходимо выполнять acquire() и release() замка Z , чтобы функция f могла правильно работать в многопоточном приложении? (Как обычно, нужно минимизировать общее время, на которое запирается замок)
def f(x): # 1 fc = open("file.txt", "w+") # 2 fc.write(x) # 3 fc.write("\n") # 4 fc.close() # 5
Объекты a и b принадлежат одному классу C . Какие из следующих выражений будут, скорее всего, иметь значение «истина» сразу после создания?
С помощью каких функций модуля re можно получить все строки, соответствующие заданному регулярному выражению r , в порядке их вхождения в строку s ?
Методы объекта Cursor модуля MySQLdb в Python
Объект Cursor представляет собой курсор базы данных, который создается для объекта соединения и используется для управления контекстом операции выборки. Курсоры, созданные из одного и того же соединения, не изолированы, т. е. любые изменения, внесенные в базу данных курсором, немедленно видны другим курсорам. Курсоры, созданные из разных соединений, могут или не могут быть изолированы, в зависимости от того, как реализована поддержка транзакций.
Атрибуты и методы объекта Cursor .
- Cursor.arraysize количество строк, которые нужно извлечь за один раз,
- Cursor.lastrowid возвращает id последней измененной строки в таблице,
- Cursor.rowcount возвращает количество строк, созданных последним запросом,
- Cursor.rownumber должен возвращать текущий индекс курсора в результирующем наборе,
- Cursor.callproc() вызывает хранимую процедуру,
- Cursor.close() немедленно закрывает курсор,
- Cursor.info() возвращает некоторую информацию о последнем запросе,
- Cursor.execute() подготавливает и выполняет запрос к базе данных,
- Cursor.executemany() выполняет множественные запросы к базе данных,
- Cursor.fetchone() получает одну (первую) строку из результатов запроса,
- Cursor.fetchmany() получает следующий набор строк размером size ,
- Cursor.fetchall() получает все или оставшиеся строки результата запроса,
- Cursor.nextset() перемещает курсор к следующему набору результатов,
- Cursor.next() возвращает следующую строку результата запроса,
- Cursor.__iter__() обеспечивает совместимость с протоколом итерации,
- Cursor.scroll() прокручивает курсор в наборе результатов до новой позиции,
- Пример работы с курсором.
Cursor.arraysize :
Свойство Cursor.arraysize для чтения/записи указывает количество строк, которые нужно извлечь за один раз с помощью Cursor.fetchmany() . По умолчанию равен 1, что означает извлечение одной строки за раз.
Cursor.lastrowid :
Свойство Cursor.lastrowid только для чтения, возвращает id последней измененной строки в таблице (некоторые версии MySQL возвращают идентификатор строки только при выполнении одной операции INSERT ). Если операция не может установить идентификатор строки id или если таблица базы данных не имеет столбца id , то этот атрибут возвращает значение None .
Семантика Cursor.lastrowid не определена, если последний выполненный запрос изменил более одной строки, например, при использовании INSERT с Cursor.executemany() .
query = "INSERT INTO table (field1, field2, field3) VALUES (%s, %s, %s)" cursor.execute(query, (param1, param2, param3,)) # получаем `id` вставленной записи last_id = cursor.lastrowid)
Cursor.rowcount :
Свойство Cursor.rowcount только для чтения, возвращает количество строк, созданных последним Cursor.execute() (для операторов SQL, таких как SELECT ), или затронутых (для операторов SQL, таких как UPDATE или INSERT ).
Свойство Cursor.rowcount равен -1, если над курсором не было выполнено Cursor.execute() или интерфейс не может определить количество строк последней операции.
Примечание. Будущие версии спецификации Python DB API могут переопределить последний случай, чтобы объект возвращал None вместо -1.
cursor.execute("SELECT spam, eggs, sausage FROM breakfast") if cursor.rowcount > 0: # если есть результаты # то проходимся по списку кортежей с результатами запроса for row in cursor.fetchall(): # извлекаем данные из кортежа с результатами spam = row[0] eggs = row[1] sausage = row[2]
Cursor.rownumber :
Свойство Cursor.rownumber только для чтения, должен возвращать текущий индекс курсора в результирующем наборе, отсчитываемый от 0, или None , если индекс не может быть определен.
Индекс можно рассматривать как индекс курсора в последовательности (результирующем наборе). Следующая операция выборки извлечет строку с индексом Cursor.rownumber в этой последовательности.
Cursor.callproc(procname [, parameters]) :
Метод Cursor.callproc() вызывает хранимую процедуру procname с последовательностью аргументов parameters . Возвращает исходные аргументы. Поддержка хранимых процедур работает только с MySQL версии 5.0 и новее.
Примечание о совместимости: PEP-249 указывает, что при наличии параметров OUT или INOUT должны быть возвращены измененные значения. Это не всегда возможно с MySQL. Аргументы хранимой процедуры должны передаваться как переменные сервера и могут быть возвращены только с помощью оператора SELECT . Так как хранимая процедура может возвращать ноль или более наборов результатов, модуль MySQLdb не может определить, есть ли наборы результатов для выборки, прежде чем будут доступны измененные параметры.
Параметры хранятся на сервере как @_*procname*_*n* , где n — позиция аргумента. То есть, если используется cursor.callproc(«foo», (a, b, c)) , то параметры будут доступны с помощью запроса SELECT @_foo_0 as foo_0, @_foo_1 as foo_1 и @_foo_2 as foo_2 .
Примечание о совместимости: Похоже, что выполнение инструкции SQL CALL создает пустой результирующий набор, который появляется после любых результирующих наборов, которые могут быть сгенерированы хранимой процедурой. Таким образом, всегда нужно будет использовать метод Cursor.nextset() для перебора результатов.
Cursor.close() :
Метод Cursor.close() немедленно закрывает курсор. Будущие операции будут вызывать исключение `MySQLdb.ProgrammingError’. Если используются курсоры на стороне сервера, то очень важно закрыть курсор, когда он больше не нужен, и особенно перед созданием нового.
Модуль не представляет менеджер контекста для закрытия открытого курсора. Для этих целей можно использовать функцию стандартной библиотеки contextlib.closing() .
from MySQLdb import connect from contextlib import closing # поднимаем соединение с базой данных db = connect('user': 'user', 'password': 'password', 'db': 'test_db') # открываем db.cursor() в менеджере контекста with closing(db.cursor()) as cursor: cursor.execute("SELECT spam, eggs, sausage FROM breakfast") . .
Cursor.info() :
Метод Cursor.info() возвращает некоторую информацию о последнем запросе. Обычно этот метод не используется. Если есть какие-либо предупреждения MySQL, то это должно привести к выдаче предупреждения через MySQLdb.Warning и/или предупреждения Python. Также, по умолчанию предупреждение приводит к появлению сообщения на консоли. Можно отфильтровать их или вызвать предупреждение, которое будет выдано как исключение.
Cursor.execute(operation [, parameters]) :
Метод Cursor.execute() подготавливает и выполняет operation к базе данных (запрос или SQL-команду). Аргумент parameters могут быть предоставлены в виде кортежа или сопоставления и будут привязаны к переменным в operation . Переменные указываются в нотации, специфичной для базы данных (подробности смотрите в описании аргумента paramstyle функции MySQLdb.connect() ).
Ссылка на операцию operation останется за курсором. Если снова передается тот же объект операции, то курсор может оптимизировать свое поведение. Это наиболее эффективно для алгоритмов, в которых используется одна и та же операция, но к ней привязаны разные parameters (много раз).
Возвращает список объектов, представляющие выборку строк таблицы базы данных в зависимости от используемого класса курсора или None , если запрос вернул пустую выборку.
max_price=5 cursor.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price %s""", (max_price,))
Cursor.executemany(operation, seq_of_parameters) :
Метод Cursor.executemany() подготавливает operation (множественный запрос) к базы данных (запрос или SQL-команду), а затем выполняет его для всех значений последовательности параметров или сопоставлений, найденных в последовательности seq_of_parameters .
Использование этого метода для операции, которая создает один или несколько результирующих наборов, представляет собой неопределенное поведение.
К этому методу применимы те же комментарии, что и для Cursor.execute() .
cursor.executemany( """INSERT INTO breakfast (name, spam, eggs, sausage, price) VALUES (%s, %s, %s, %s, %s)""", [ ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ), ("Not So Much Spam Plate", 3, 2, 0, 3.95 ), ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 ) ] )
Cursor.fetchone() :
Метод Cursor.fetchone() получает одну (первую) строку набора результатов запроса, возвращая одну последовательность, или None , если больше нет доступных данных.
Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).
max_price=5 cursor.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price %s""", (max_price,)) # получаем первый кортеж из списка # кортежей с результатами запроса row = cursor.fetchone() # извлекаем результаты из кортежа spam = row[0] eggs = row[1] sausage = row[2]
Cursor.fetchmany([size=cursor.arraysize]) :
Метод Cursor.fetchmany() получает следующий набор строк результата запроса, возвращая список кортежей. Когда больше нет доступных строк, то возвращается пустая последовательность.
Количество строк для выборки за вызов определяется аргументом size . Если он не указан, то размер массива курсора определяет количество извлекаемых строк. Метод попытаться получить столько строк, сколько указано аргументом size . Если это невозможно из-за того, что указанное количество строк недоступно, то может быть возвращено меньшее количество строк.
Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).
Обратите внимание, что с аргументом size связаны соображения производительности. Для оптимальной производительности, лучше всего использовать свойство Cursor.arraysize . Если используется аргумент size , то для него лучше сохранять одно и то же значение от одного вызова Cursor.fetchmany() до следующего.
Cursor.fetchall() :
Метод Cursor.fetchall() получает все (оставшиеся) строки результата запроса, возвращая их в виде список кортежей.
Обратите внимание, что свойство Cursor.arraysize может повлиять на производительность этой операции.
Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).
cursor.execute("SELECT spam, eggs, sausage FROM breakfast") # проходимся по списку кортежей с результатами запроса for row in cursor.fetchall(): # извлекаем данные из кортежа с результатами spam = row[0] eggs = row[1] sausage = row[2]
Cursor.nextset() :
Метод Cursor.nextset() перемещает курсор к следующему набору результатов, отбрасывая оставшиеся строки в текущем наборе результатов. Если дополнительных наборов результатов нет, то возвращается None , в противном случае он возвращает истинное значение.
Обратите внимание, что MySQL не поддерживает несколько наборов результатов до версии 4.1.
Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).
Cursor.next() :
Метод Cursor.next() возвращает следующую строку из выполняемого в данный момент оператора SQL, используя ту же семантику, что и Cursor.fetchone() .
Когда набор результатов исчерпан, появляется исключение StopIteration .
Cursor.__iter__() :
Метод Cursor.__iter__() возвращает self , чтобы сделать курсоры совместимыми с протоколом итерации.
Cursor.scroll(value [, mode=’relative’ ]) :
Метод Cursor.scroll() прокручивает курсор в наборе результатов до новой позиции value в соответствии с режимом mode .Если режим mode=’relative’ (по умолчанию), то значение берется как смещение к текущей позиции в результирующем наборе, если установлено mode=’absolute’ , то значение указывает абсолютную целевую позицию.
Если операция прокрутки выходит за пределы набора результатов, то возникает исключение IndexError . В этом случае позиция курсора остается неопределенной.
Пример работы с курсором.
Модуль MySQLdb не имеет встроенных менеджеров контекста для закрытия курсора. Для удобной очистки оперативной памяти от результатов объекта курсора лучше использовать функцию стандартной библиотеки contextlib.closing .
from MySQLdb import connect, cursors, Error from contextlib import closing # конфигурация соединения с базой данных MYSQLCONF = 'host': 'localhost', # хост базы данных 'user': '******', # имя пользователя базы данных 'password': '******', # пароль пользователя базы данных 'db': 'test_db', # имя базы данных 'charset': 'utf8', # используемая кодировка базы данных 'autocommit': True, # автоматический cursor.commit() # извлекаемые строки из БД принимают вид словаря 'cursorclass': cursors.DictCursor > # поднимаем соединение с базой данных db = connect(**MYSQLCONF) # открываем курсор при помощи `contextlib.closing` with closing(db.cursor()) as cursor: # создаем строку с запросом с использованием подстановок query = """INSERT INTO table (field1, field2, field3) VALUES (%s, %s, %s)""" try: # выполняем запрос с необходимыми параметрами cursor.execute(query, (param1, param2, param3,)) # здесь должна быть строка с командой `cursor.commit()` # но ее нет, т.к. соединение настроено с 'autocommit': True except Error as err: # Класс `Error` выводит ошибки, связанные с работой базы данных # и не обязательно находящихся под контролем программиста print(err) # если нужно, то можно получить `id` вставленной записи print('lastrowid =>', cursor.lastrowid) # далее какой-то код программы .
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функция connect() модуля MySQLdb
- Методы объекта Cursor модуля MySQLdb
- Исключения, определяемые модулем MySQLdb
- Реализация интерфейса MySQL C API в модуле MySQLdb Python
- Подмодуль times модуля MySQLdb
- Подмодуль converters модуля MySQLdb
- MySQL: Типы хранимых данных
- MySQL: CONVERT() и CAST(), преобразование типов
- MySQL: Неявные преобразования типов в вычислениях
- MySQL: Функции для работы со строками
- MySQL: Функции для работы с датой и временем
- MySQL: Временные интервалы и арифметика с датами
- MySQL: Математические функции
- MySQL: Агрегатные (групповые) функций
- MySQL: SELECT cоставление запросов
- MySQL: CASE и IF() в запросах SELECT
- MySQL: Поиск по шаблону, LIKE в запросах SELECT
- MySQL: Поиск по регулярному выражению
- MySQL: Использование WHERE в запросах
- MySQL: Использование GROUP BY и HAVING
- MySQL: LEFT JOIN и INNER JOIN объединение таблиц
- MySQL: UNION объединение запросов
- MySQL: UPDATE обновление данных таблицы
- MySQL: INSERT/REPLACE добавление данных в таблицу
- MySQL: DELETE/TRUNCATE удаление записи/очистка данных таблицы
- MySQL: CREATE TABLE создание таблиц
- Импорт CSV-файла в MySQL таблицу, экспорт данных в CSV
- MySQL: ALTER TABLE изменение таблицы
- MySQL: Хранимые процедуры и функции
- MySQL: События EVENT и планировщик событий
- MySQL: CREATE/ALTER USER и права GRANT/ROLE
- MySQL: Сброс пароля root на ОС Linux/Windows
- Логирование ВСЕХ и/или МЕДЛЕННЫХ запросов к БД MYSQL
- Кэширование запросов на MySQL-сервере
- Как конвертировать БД MySQL в требуемую кодировку
API-спецификация баз данных языка Python, версия 2.0 (Database API Specification 2.0)
Этот API был определен для поощрения сходства между модулями Python, используемыми для доступа к базам данных. Таким образом мы надеемся достичь соответствия, которое приведет к более понятным модулям, коду, который в целом легче переносим между базами данных и более широкому спектру возможностей языка Python по доступу к базам данных.
Спецификация интерфейса состоит из нескольких разделов:
Комментарии и вопросы по этой спецификации могут быть направлены в адрес Специальной группы по доступу к базам данных из Python.
За дополнительной информацией о доступе к базам данных из Python и о имеющихся пакетах обращайтесь к Руководству по базам данных на www.python.org.
Этот документ описывает Python Database API Specification 2.0. Предыдущая версия 1.0 все еще доступна для справки. Поощряется использование последней версии спецификации в качестве основы для нового интерфейса программистами, пишущими пакеты.
Интерфейс модуля
Доступ к базе данных реализуется с помощью объектов соединения (connection objects). Модуль должен предоставлять для них следующий конструктор:
connect(параметры. )
Конструктор для создания соединения с базой данных. Возвращает Объект соединения. Имеет ряд параметров, которые зависят от базы данных. [1]
Должны быть определены следующие глобальные переменные модуля:
apilevel
Строковая константа, обозначающая поддерживаемый уровень DB API. В настоящее время допускаются только строки ‘1.0’ и ‘2.0’ .
Если не задана, предполагается уровень Database API 1.0.
threadsafety
Целочисленная константа, обозначающая уровень нитебезопасности, поддерживаемый данным интерфейсом. Возможные значения:
0 = Модуль не может разделяться нитями.
1 = Нити могут разделять модуль, но не соединения.
2 = Нити могут разделять и модуль, и соединения.
3 = Нити могут разделять модуль, соединения и курсоры.
Разделение в вышеуказанном контексте означает, что две нити могут использовать ресурс, не используя внешний объект синхронизации (mutex) для блокировки. Заметьте, что вы не всегда можете обеспечить нитебезопасность для внешних ресурсов, управляя доступом с помощью семафора: ресурс может использовать глобальные переменные или другие внешние ресурсы, находящиеся вне вашего контроля.
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’. Предупреждения не рассматриваются как ошибки и поэтому не должны использовать этот класс в качестве базового. Этот класс должен быть производным от класса Python StandardError (определенного в модуле exceptions).
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()
Завершить любую незавершенную транзакцию в базе данных. Заметьте, что если база поддерживает автоматическую фиксацию, в исходном положении она должна быть отключена. Интерфейс может предоставлять метод для включения автофиксации.
Модули баз данных, не поддерживающих транзакции, должны реализовывать этот метод в виде заглушки.
rollback()
Этот метод не является обязательным, поскольку не все базы данных обеспечивают поддержку транзакций.[3]
В случае, если база данных обеспечивает поддержку транзакций, этот метод заставляет базу данных откатить к началу незавершенную транзакцию. Закрытие соединения без предварительной явной фиксации изменений приведет к неявному откату.
cursor()
Вернуть новый Объект курсора, используя соединение. Если база не обеспечивает поддержку концепции курсора, модуль должен эмулировать курсоры, используя другие средства в пределах, необходимых для этой спецификации. [4]
Объекты курсора
Эти объекты представляют курсор базы данных, используемый для управления контекстом операции выборки.
Объекты курсора должны поддерживать следующие методы и атрибуты:
description
Этот read-only атрибут представляет собой последовательность семизначных последовательностей. Каждая из таких последовательностей содержит информацию, описывающую одну колонку результата: ( name, type_code, display_size, internal_size, precision, scale, null_ok ). Этот атрибут будет принимать значение None для операций, не возвращающих строки или в случае, когда курсор еще не выполнил операцию с помощью метода executeXXX() .
Type_code может интерпретироваться путем сравнения его с Объектами типа, определенными в следующем разделе.
rowcount
Этот read-only атрибут определяет число строк выбранное (для предложений DQL наподобие select ) или затронутое (для модифицирующих предложений DML наподобие update или insert ) последним вызовом executeXXX() .
Этот атрибут принимает значение -1 в случае, если над курсором не выполнен ни один executeXXX() или если интерфейс не может определить количество строк в последней операции.[7]
callproc(имя процедуры[,параметры])
Этот метод необязателен, поскольку не все базы данных поддерживают хранимые процедуры.[3]
Вызвать хранимую процедуру с заданным именем. Последовательность параметров должна содержать один вход для каждого аргумента, ожидаемого процедурой. Результат вызова возвращается в виде модифицированной копии исходной последовательности. Input-параметры остаются нетронутыми, output и input/output параметры могут быть заменены новыми значениями.
Процедура может также обеспечивать на выходе результирующее множество. Оно затем должно быть доступно через стандартные методы fetchXXX() .
close()
Закрыть курсор (сейчас, а не при вызове __del__ ). С момента вызова и далее курсор становится неиспользуемым; в случае попытки обратиться к некоторой операции курсора, возбуждается исключение Error (или подкласс).
execute(операция[,параметры])
Подготовить и выполнить операцию базы данных (запрос или команду). Параметры могут обеспечиваться в виде последовательности или словаря и будут привязаны к переменным в операции. Переменные задаются в нотации, специфической для базы данных (подробно см. атрибут модуля paramstyle ). [5]
Ссылка на операцию будет храниться курсором. Если такой же объект операции передается снова, курсор может оптимизировать свое поведение. Это наиболее эффективно для алгоритмов, в которых много раз используются одна и та же операция, но с привязкой различных параметров.
Для максимальной эффективности при повторном использовании операции, лучше всего воспользоваться методом setinputsizes() для того, чтобы заранее задать типы и размеры параметров. Для параметра допустимо несоответствие заранее определенной информации; реализация должна компенсировать это, возможно, с некоторой потерей эффективности.
Параметры могут быть также определены как список кортежей, например, для вставки множества строк в рамках одной операции, но это не поощряется: вместо этого следует воспользоваться executemany() .
Возвращаемые значения не определены.
executemany(операция, seq_of_parameters)
Подготовить операцию базы данных (запрос или команду) и затем выполнить ее для всех последовательностей или словарей, найденных в последовательности параметров seq_of_parameters .
Модули свободны в реализации этого метода либо с использованием множественных вызовово метода execute(), либо с использованием массивных операций для того, чтобы заставить базу данных обработать последовательность целиком за один вызов.
Примечания, данные для execute() , применимы также и к этому методу.
Возвращаемые значения не определены.
fetchone()
Выбирает следующую строку из результирующего множества — результата запроса, возвращая одиночную последовательность, или None в случае, когда данных больше нет. [6]
Исключение Error (или подкласс) возбуждается, если предыдущий вызов executeXXX() не вернул результирующего множества, либо еще не было ни одного такого вызова.
fetchmany([размер=cursor.arraysize])
Выбирает следующий набор строк из результата запроса, возвращая последовательность последовательностей (например, список кортежей). Пустая последовательность возвращается, если больше нет никаких строк.
Число строк для выборки за один вызов определяется параметром. Если параметр не задан, число строк для выборки определяет атрибут курсора arraysize . Этот метод должен попытаться выбрать столько строк, сколько указано в параметре. Если такое количество строк недоступно, может быть возвращено меньшее число строк.
Исключение Error (или подкласс) возбуждается, если предыдущий вызов executeXXX() не вернул результирующего множества, либо еще не было ни одного такого вызова.
Отметьте, что есть некоторые соображения, связанные с параметром размера. Для достижения оптимальной производительности обычно лучше всего пользоваться атрибутом arraysize . Если используется параметр размера, то лучше, чтобы он сохранял одну и ту же величину от одного вызова fetchmany() к следующему.
fetchall()
Выбирает все (оставшиеся) строки результата запроса, возвращая их в виде последовательности последовательностей (например, списка кортежей). Заметьте, что атрибут курсора arraysize может влиять на производительность этой операции.
Исключение Error (или подкласс) возбуждается, если предыдущий вызов executeXXX() не вернул результирующего множества, либо еще не было ни одного такого вызова.
nextset().
Этот метод не является обязательным, поскольку не все базы данных поддерживают несколько результирующих множеств. [3]
Этот метод заставит курсор перейти на следующее имеющееся множество, игнорируя все оставшиеся строки текущего множества.
Если больше множеств нет, метод возвращает None . Иначе он возвращает значение истинности, и последующие обращения к методам выборки будут возвращать строки из следующего результирующего множества.
Исключение Error (или подкласс) возбуждается, если предыдущий вызов executeXXX() не вернул результирующего множества, либо еще не было ни одного такого вызова.
arraysize
Этот read/write атрибут определяет число строк, выбираемых fetchmany() за один раз. По умолчанию имеет значение 1, означающее выборку одной строки за один раз.
Реализации должны придерживаться этого значения в том, что касается метода fetchmany() , однако они имеют полное право выбирать по одной строке за раз при взаимодействии с базой данных. Этот атрибут может быть также использован в реализации executemany() .
setinputsizes(sizes)
Может использоваться перед вызовом executeXXX() для предварительного определения областей памяти под параметры операции.
Параметр sizes (размеры) определен как последовательность — один элемент для каждого входного параметра. Элемент должен быть объектом типа (Type Object, например, IntType), соответствующим типу параметра, или целым числом, определяющим максимальную длину строкового параметра. Если элемент имеет значение None , под этот столбец не будет зарезервировано заранее определенной области памяти (это полеэно, чтобы избежать выделения областей для больших вводов).
Этот метод может использоваться перед вызовом метода executeXXX() .
Реализации могут оставить этот метод заглушкой, а пользователи могут не использовать его.
setoutputsize(размер[,столбец])
Устанавливает размер буфера столбца для выборки больших столбцов (например, LONG, BLOB и др.). Столбец задается как индекс (номер столбца) в результатирующем множестве. Если столбец не задан, устанавливается размер по умолчанию для всех больших столбцов в курсоре.
Этот метод может использоваться перед вызовом метода executeXXX() .
Реализации могут оставить этот метод заглушкой, а пользователи могут не использовать его.
Объекты типа и конструкторы
Многие базы данных требуют входных данных в определенном формате для привязки к input-параметрам операций. Например, если данные предназначены для столбца типа DATE, они должен быть подготовлены для базы данных в определенном строковом формате. Такие же проблемы существуют для столбцов «Row ID» или больших бинарных элементов (например, blob’ов или столбцов RAW). Это представляет проблему для Python, поскольку параметры метода executeXXX() не типизированы. Когда модуль базы данных видит строковый объект Python, он не знает, нужно ли его привязывать как простой символьный столбец (CHAR), как необработанный бинарный элемент (BINARY) или как дату (DATE).
Для преодоления этой проблемы модуль должен обеспечивать описанные ниже конструкторы для создания объектов, которые могут хранить специальные значения. Когда такой объект передется методам курсора, модуль может определить правильный тип входного параметра и привязать его соответствующим образом.
Атрибут объекта курсора description возвращает информацию о каждом из столбцов результата запроса. Код типа type_code должен быть проверен на равенство одному из Объектов типа, описанных ниже. Объекты типа могут быть равны более чем одному коду типа (например, DATETIME может быть равен кодам типа для столбцов даты, времени и временной метки; подробно см. Советы по реализации, данные ниже).
Модуль экспортирует следующие конструкторы и одноэлементные множества:
Date(год,месяц,день)
Эта функция создает объект, содержащий значение даты.
Time(час,минута,секунда)
Эта функция создает объект, содержащий значение времени.
Timestamp(год,месяц,день,час,минута,секунда)
Эта функция создает объект, содержащий значение временной метки.
DateFromTicks(отсчеты)
Эта функция создает объект, содержащий значение даты, из заданного количества отсчетов (ticks) (числа секунд с начала эпохи; подробно см. документацию по стандартному модулю time языка Python).
TimeFromTicks(отсчеты)
Эта функция создает объект, содержащий значение времени, из заданного количества отсчетов (ticks) (числа секунд с начала эпохи; подробно см. документацию по стандартному модулю time языка Python).
TimestampFromTicks(отсчеты)
Эта функция создает объект, содержащий значение временной метки, из заданного количества отсчетов (ticks) (числа секунд с начала эпохи; подробно см. документацию по стандартному модулю time языка Python).
BINARY(строка)
Эта функция создает объект, способный содержать бинарное (длинное) строковое значение.
STRING
Этот объект типа используется для описания строковых столбцов в базе данных (например, CHAR).
BINARY
Этот объект типа используется для описания (длинных) бинарных столбцов в базе данных (например, LONG, RAW, BLOB).
NUMBER
Этот объект типа используется для описания числовых столбцов в базе данных.
DATETIME
Этот объект типа используется для описания в базе данных столбцов дата/время.
ROWID
Этот объект типа используется для описания в базе данных столбцов «Row ID».
NULL-значения SQL представляются с помощью None при вводе и выводе.
Примечание: Использование отсчетов Unix при взаимодействии с базой данных может создать проблемы из-за ограниченности спектра описываемых ими дат.
Советы по реализации
- Предпочтительными типами для объектов дата/время являются те, что определены в пакете mxDateTime . Он обеспечивает необходимые конструкторы и методы как на уровне Python, так и Cи.
- Предпочтительным типом объекта для бинарных объектов являются типы буферов, доступные в стандартном Python, начиная с версии 1.5.2. За дополнительной информацией обращайтесь к документации по Python. Для информации по интерфейсу к Си взгляните в 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
В языке Си для создания объектов исключений вы можете использовать API PyErr_NewException(fullname, base, NULL).
Основные изменения в версии 2.0 относительно версии 1.0
Python Database API 2.0 вводит несколько значительных изменений относительно версии 1.0. Ввиду того, что некоторые из этих изменений приведут к нарушению работы существующих скриптов, основанных на DB API 1.0, старший номер версии был увеличен для отражения этого изменения.
- Отпала необходимость в отдельном модуле dbi, эта функция встроена в сам интерфейс модуля.
- Были добавлены новые конструкторы и Объекты типа для значений дата/время, Объекты типа RAW были переименованы в BINARY. Полученный набор должен охватывать все основные типы данных, обычно имеющиеся в современных базах данных SQL.
- Были добавлены новые константы (apilevel, threadlevel, paramstyle) и методы (executemany, nextset) для обеспечения лучшей привязки к базам данных.
- Теперь ясно определена семантика .callproc(), необходимой для вызова хранимых процедур.
- Изменено определение возвращаемого значения .execute(). Ранее возвращаемое значение основывалось на типе предложения SQL (что было крайне трудно правильно реализовать) — сейчас оно не определено; пользуйтесь вместо него более гибким атрибутом .rowcount. Модули свободны в возвращении значений в старом виде, однако это больше не предписывается спецификацией и должно считаться зависящим от интерфейса базы данных.
- Исключения, основанные на классах, были встроены в спецификацию. Реализаторы модуля свободны расширить схему исключений, определенную в этой спецификации, путем наследования от описанных классов исключений.
Открытые вопросы
- Определить подходящее значение возврата .nextset() для случая наличия нового результирующего множества.
- Создать числовой тип с фиксированной точкой для использования в качестве не имеющего потерь точности денежного и десятичного форматов.
Сноски
1. В качестве руководящего указания параметры конструктора соединения должны быть реализованы как ключевые параметры для более интуитивного использования и согласно следующей последовательности параметров:
| dsn | = Источник данных в виде строки | |
| user | = Имя пользователя в виде строки | (необязательно) |
| password | = Пароль в виде строки | (необязательно) |
| host | = Имя хоста | (необязательно) |
| database | = Имя базы данных | (необязательно) |
Например, соединение может выглядеть следующим образом:
2. Реализаторы модуля должны отдавать предпочтение ‘numeric’, ‘named’ и ‘pyformat’ перед другими форматами, так как это предполагает большую четкость и гибкость.
3. Если база данных не поддерживает функцию, необходимую для метода, интерфейс должен возбуждать исключение при попытке использования этого метода.
Предпочтительный подход заключается в отказе от реализации такого метода, тем самым приводя к генерации языком Python исключения AttributeError в случае, если запрашивается этот метод. Это позволяет программисту проверить возможности базы данных, используя стандартную функцию hasattr() .
Для некоторых динамически конфигурируемых интерфейсов может не годиться необходимость динамического создания метода. Эти интерфейсы в таком случае должны вызывать исключение NotSupportedError для указания на невозможность исполнения отката, когда метод уже вызван.
4. Интерфейс базы данных может поддержать именованные курсоры путем разрешения строкового аргумента для метода. Это свойство не является частью спецификации, поскольку оно усложняет семантику методов .fetchXXX() .
5. Модуль будет использовать метод __getitem__ объекта параметров для отображения как позиций (целых чисел), так и имен (строк) в значения параметров. Это позволяет использовать в качестве входных величин как последовательности, так и словари.
Термин «привязка» относится к процессу привязки входного значения к буферу выполнения базы данных. В практических терминах это означает, что входное значение напрямую используется в качестве значения в операции. От клиента не должно требоваться «выделение» («escaping») этого значения таким образом, чтобы его можно было использовать — значение должно быть равно действительному значению из базы данных.
6. Заметьте, что интерфейс может реализовывать выборку строк с использованием массивов и другие виды оптимизации. Нет гарантии, что обращение к этому методу сдвинет соответствующий курсор вперед только на одну строку.
7. Атрибут rowcount может быть запрограммирован способом, динамически обновляющим его значение. Это может быть полезно для баз данных, возвращающих осмысленные значения rowcount только после первого вызова метода .fetchXXX() .
Автор: Python.org
Объект–курсор
Курсор (от англ. cursor — CURrrent Set Of Records, текущий набор записей) служит для работы с результатом запроса. Результатом запроса обычно является одна или несколько прямоугольных таблиц со столбцами–полями и строками–записями. Приложение может читать и обрабатывать полученные таблицы и записи в таблице по одной, поэтому в курсоре хранится информация о текущей таблице и записи. Конкретный курсор в любой момент времени связан с выполнением одной SQL–инструкции.
Атрибуты объекта–курсора тоже определены DB-API:
• arraysize Атрибут, равный количеству записей, возвращаемых методом fetchmany(). По умолчанию равен 1.
• callproc(procname[, params]) Вызывает хранимую процедуру procname с параметрами из изменчивой последовательности params. Хранимая процедура может изменить значения некоторых параметров последовательности. Метод может возвратить результат, доступ к которому осуществляется через fetch–методы.
• close() Закрывает объект–курсор.
• description Этот доступный только для чтения атрибут является последовательностью из семиэлементных последовательностей. Каждая из этих последовательностей содержит информацию, описывающую один столбец результата:
• (name, type_code, display_size, internal_size, precision, scale, null_ok) Первые два элемента (имя и тип) обязательны, а вместо остальных (размер для вывода, внутренний размер, точность, масштаб, возможность задания пустого значения) может быть значение None. Этот атрибут может быть равным None для операций, не возвращающих значения.
• execute(operation[, parameters]) Исполняет запрос к базе данных или команду СУБД. Параметры (parameters) могут быть представлены в принятой в базе данных нотации в соответствии с атрибутом paramstyle, описанным выше.
• executemany(operation, seq_of_parameters) Выполняет серию запросов или команд, подставляя параметры в заданный шаблон. Параметр seq_of_parameters задает последовательность наборов параметров.
• fetchall() Возвращает все (или все оставшиеся) записи результата запроса.
• fetchmany([size]) Возвращает следующие несколько записей из результатов запроса в виде последовательности последовательностей. Пустая последовательность означает отсутствие данных. Необязательный параметр size указывает количество возвращаемых записей (реально возвращаемых записей может быть меньше). По умолчанию size равен атрибуту arraysize объекта–курсора.
• fetchone() Возвращает следующую запись (в виде последовательности) из результата запроса или None при отсутствии данных.
• nextset() Переводит курсор к началу следующего набора данных, полученного в результате запроса (при этом часть записей в предыдущем наборе может остаться непрочитанной). Если наборов больше нет, возвращает None. Не все базы данных поддерживают возврат нескольких наборов результатов за одну операцию.
• rowcount Количество записей, полученных или затронутых в результате выполнения последнего запроса. В случае отсутствия execute–запросов или невозможности указать количество записей равен–1.
• setinputsizes(sizes) Предопределяет области памяти для параметров, используемых в операциях. Аргумент sizes задает последовательность, где каждый элемент соответствует одному входному параметру. Элемент может быть объектом–типом соответствующего параметра или целым числом, задающим длину строки. Он также может иметь значение None, если о размере входного параметра ничего нельзя сказать заранее или он предполагается очень большим. Метод должен быть вызван до execute–методов.
• setoutputsize(size[, column]) Устанавливает размер буфера для выходного параметра из столбца с номером column. Если column не задан, метод устанавливает размер для всех больших выходных параметров. Может использоваться, например, для получения больших бинарных объектов (Binary Large Object, BLOB).