sqlite3.md
1> **Источник:** https://python-all.ru/3.7/library/sqlite3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) – интерфейс DB-API 2.0 для баз данных SQLite89**Исходный код:** [Lib/sqlite3/](https://python-all.ru/src/3.7/Lib/sqlite3)1011---1213SQLite – это библиотека на C, которая предоставляет легковесную дисковую базу данных, не требующую отдельного серверного процесса, и позволяет обращаться к базе данных с помощью нестандартного варианта языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также можно создать прототип приложения на SQLite, а затем перенести код на более крупную базу данных, например PostgreSQL или Oracle.1415Модуль sqlite3 написан Герхардом Харингом. Он предоставляет SQL-интерфейс, соответствующий спецификации DB-API 2.0, описанной в [**PEP 249**](https://python-all.ru/3.7/library/sqlite3.html).1617Чтобы использовать модуль, сначала необходимо создать объект [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection), который представляет базу данных. Здесь данные будут храниться в файле `example.db`:1819```python20import sqlite321conn = sqlite3.connect('example.db')22```2324Также можно указать специальное имя `:memory:` для создания базы данных в оперативной памяти.2526После получения [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection) можно создать объект [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor) и вызвать его метод [`execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute) для выполнения SQL-команд:2728```python29c = conn.cursor()3031# Создать таблицу32c.execute('''CREATE TABLE stocks33 (date text, trans text, symbol text, qty real, price real)''')3435# Вставить строку данных36c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")3738# Сохранить (зафиксировать) изменения39conn.commit()4041# Также можно закрыть соединение, если работа с ним завершена.42# Все изменения должны быть зафиксированы, иначе они будут потеряны.43conn.close()44```4546Сохранённые данные являются постоянными и доступны в последующих сеансах:4748```python49import sqlite350conn = sqlite3.connect('example.db')51c = conn.cursor()52```5354Обычно в SQL-операциях требуется использовать значения из переменных Python. Не следует собирать запрос с помощью строковых операций Python, потому что это небезопасно; это делает программу уязвимой для атак SQL-инъекций (см. [https://xkcd.com/327/](https://python-all.ru/3.7/library/sqlite3.html) – забавный пример того, что может пойти не так).5556Вместо этого используется подстановка параметров DB-API. `?` ставится в качестве заполнителя там, где требуется значение, после чего кортеж значений передаётся вторым аргументом методу [`execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute) курсора. (Другие модули баз данных могут использовать другой заполнитель, например `%s` или `:1`.) Например:5758```python59# Никогда не делайте этого – это небезопасно!60symbol = 'RHAT'61c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)6263# Вместо этого сделайте так64t = ('RHAT',)65c.execute('SELECT * FROM stocks WHERE symbol=?', t)66print(c.fetchone())6768# Более крупный пример, вставляющий много записей за один раз69purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),70 ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),71 ('2006-04-06', 'SELL', 'IBM', 500, 53.00),72 ]73c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)74```7576Чтобы получить данные после выполнения запроса SELECT, можно либо рассматривать курсор как [итератор](https://python-all.ru/3.7/glossary.html#term-iterator), вызвать метод [`fetchone()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.fetchone) курсора для получения одной подходящей строки, либо вызвать [`fetchall()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.fetchall) для получения списка подходящих строк.7778В этом примере используется форма итератора:7980```python81>>> for row in c.execute('SELECT * FROM stocks ORDER BY price'):82 print(row)8384('2006-01-05', 'BUY', 'RHAT', 100, 35.14)85('2006-03-28', 'BUY', 'IBM', 1000, 45.0)86('2006-04-06', 'SELL', 'IBM', 500, 53.0)87('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)88```8990> **См. также**91>92> **[https://github.com/ghaering/pysqlite](https://python-all.ru/3.7/library/sqlite3.html)**93>94> Страница pysqlite – sqlite3 разрабатывается отдельно под названием «pysqlite».95>96> **[https://www.sqlite.org](https://python-all.ru/3.7/library/sqlite3.html)**97>98> Веб-страница SQLite; документация описывает синтаксис и доступные типы данных поддерживаемого диалекта SQL.99>100> **[https://www.w3schools.com/sql/](https://python-all.ru/3.7/library/sqlite3.html)**101>102> Учебные материалы, справочник и примеры для изучения синтаксиса SQL.103>104> **[**PEP 249**](https://python-all.ru/3.7/library/sqlite3.html) – спецификация API баз данных 2.0**105>106> PEP написан Марком-Андре Лембургом.107108## Функции и константы модуля109110#### `sqlite3.version`111112Номер версии этого модуля в виде строки. Это не версия библиотеки SQLite.113114#### `sqlite3.version_info`115116Номер версии этого модуля в виде кортежа целых чисел. Это не версия библиотеки SQLite.117118#### `sqlite3.sqlite_version`119120Номер версии библиотеки SQLite времени выполнения в виде строки.121122#### `sqlite3.sqlite_version_info`123124Номер версии библиотеки SQLite времени выполнения в виде кортежа целых чисел.125126#### `sqlite3.PARSE_DECLTYPES`127128Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.connect).129130Установка этого флага заставляет модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) анализировать объявленный тип для каждого возвращаемого столбца. Он выделит первое слово объявленного типа, т. е. для «integer primary key» выделит «integer», а для «number(10)» выделит «number». Затем для этого столбца он заглянет в словарь преобразователей и использует зарегистрированную там функцию преобразования для этого типа.131132#### `sqlite3.PARSE_COLNAMES`133134Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.connect).135136Установка этого заставляет интерфейс SQLite разбирать имя столбца для каждого возвращаемого столбца. Он будет искать строку вида \[mytype\] и затем определять, что 'mytype' – это тип столбца. Затем будет пытаться найти запись 'mytype' в словаре converters и использовать найденную функцию преобразования для возврата значения. Имя столбца, найденное в [`Cursor.description`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.description), не включает тип, т.е. если в SQL используется нечто вроде `'as "Expiration date [datetime]"'`, то будет выделено всё до первого `'['` для имени столбца и удалён предшествующий пробел: имя столбца будет просто "Expiration date".137138#### `sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])`139140Открывает соединение с файлом базы данных SQLite *database*. По умолчанию возвращает объект [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection), если не указана пользовательская *factory*.141142*database* is a [path-like object](https://python-all.ru/3.7/glossary.html#term-path-like-object) giving the pathname (absolute or relative to the current working directory) of the database file to be opened. You can use `":memory:"` to open a database connection to a database that resides in RAM instead of on disk.143144Когда к базе данных обращаются несколько соединений и один из процессов изменяет базу данных, база данных SQLite блокируется до завершения этой транзакции. Параметр *timeout* задаёт, как долго соединение должно ждать снятия блокировки, прежде чем возникнет исключение. Значение по умолчанию для параметра timeout – 5.0 (пять секунд).145146По поводу параметра *isolation\_level* обратитесь к свойству [`isolation_level`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.isolation_level) объектов [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection).147148SQLite изначально поддерживает только типы TEXT, INTEGER, REAL, BLOB и NULL. Если вы хотите использовать другие типы, необходимо добавить поддержку самостоятельно. Параметр *detect\_types* и использование пользовательских **преобразователей**, зарегистрированных с помощью функции модуля [`register_converter()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.register_converter), позволяют легко это сделать.149150*detect\_types* по умолчанию равен 0 (т.е. выключен, определение типов не выполняется). Вы можете установить его в любую комбинацию [`PARSE_DECLTYPES`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.PARSE_COLNAMES), чтобы включить определение типов.151152По умолчанию *check\_same\_thread* равен [`True`](https://python-all.ru/3.7/library/constants.html#True), и только создавший поток может использовать соединение. Если установлено [`False`](https://python-all.ru/3.7/library/constants.html#False), возвращаемое соединение может использоваться несколькими потоками. При использовании нескольких потоков с одним соединением операции записи должны быть сериализованы пользователем во избежание повреждения данных.153154По умолчанию модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) использует свой класс [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection) для вызова connect. Однако вы можете создать подкласс класса [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection) и заставить [`connect()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.connect) использовать ваш класс, передав его в параметре *factory*.155156Подробности см. в разделе [Типы SQLite и Python](https://python-all.ru/3.7/library/sqlite3.html#sqlite3-types) данного руководства.157158Модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) внутренне использует кэш операторов для снижения накладных расходов на разбор SQL. Если вы хотите явно задать количество операторов, кэшируемых для соединения, можно установить параметр *cached\_statements*. Текущая реализация по умолчанию кэширует 100 операторов.159160Если *uri* равно true, *database* интерпретируется как URI. Это позволяет задавать параметры. Например, чтобы открыть базу данных в режиме только для чтения, можно использовать:161162```python163db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)164```165166Дополнительную информацию об этой возможности, включая список распознаваемых параметров, можно найти в [документации SQLite URI](https://python-all.ru/3.7/library/sqlite3.html).167168Изменено в версии 3.4: Добавлен параметр *uri*.169170Изменено в версии 3.7: *database* теперь также может быть [объектом, подобным пути](https://python-all.ru/3.7/glossary.html#term-path-like-object), а не только строкой.171172#### `sqlite3.register_converter(typename, callable)`173174Регистрирует вызываемый объект для преобразования байтовой строки из базы данных в пользовательский тип Python. Вызываемый объект будет вызываться для всех значений базы данных, имеющих тип *typename*. Смотрите параметр *detect\_types* функции [`connect()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.connect), чтобы узнать, как работает определение типа. Обратите внимание, что *typename* и имя типа в запросе сравниваются без учёта регистра.175176#### `sqlite3.register_adapter(type, callable)`177178Регистрирует вызываемый объект для преобразования пользовательского типа Python *type* в один из поддерживаемых типов SQLite. Вызываемый объект *callable* принимает в качестве единственного параметра значение Python и должен возвращать значение одного из следующих типов: int, float, str или bytes.179180#### `sqlite3.complete_statement(sql)`181182Возвращает [`True`](https://python-all.ru/3.7/library/constants.html#True), если строка *sql* содержит одно или несколько полных SQL-выражений, завершающихся точкой с запятой. При этом не проверяется синтаксическая корректность SQL, только отсутствие незакрытых строковых литералов и завершение выражения точкой с запятой.183184Это можно использовать для создания оболочки для SQLite, как в следующем примере:185186```python187# Минимальная оболочка SQLite для экспериментов188189import sqlite3190191con = sqlite3.connect(":memory:")192con.isolation_level = None193cur = con.cursor()194195buffer = ""196197print("Enter your SQL commands to execute in sqlite3.")198print("Enter a blank line to exit.")199200while True:201 line = input()202 if line == "":203 break204 buffer += line205 if sqlite3.complete_statement(buffer):206 try:207 buffer = buffer.strip()208 cur.execute(buffer)209210 if buffer.lstrip().upper().startswith("SELECT"):211 print(cur.fetchall())212 except sqlite3.Error as e:213 print("An error occurred:", e.args[0])214 buffer = ""215216con.close()217```218219#### `sqlite3.enable_callback_tracebacks(flag)`220221По умолчанию трассировки не отображаются для пользовательских функций, агрегатов, преобразователей, колбэков авторизатора и т.д. Для отладки можно вызвать эту функцию, установив для *flag* значение `True`. После этого трассировки будут отображаться из колбэков на `sys.stderr`. Используйте [`False`](https://python-all.ru/3.7/library/constants.html#False), чтобы снова отключить эту возможность.222223## Объекты подключения224225#### `class sqlite3.Connection`226227Соединение с базой данных SQLite обладает следующими атрибутами и методами:228229#### `isolation_level`230231Получает или устанавливает текущий уровень изоляции по умолчанию. [`None`](https://python-all.ru/3.7/library/constants.html#None) для режима автокоммита или одно из значений «DEFERRED», «IMMEDIATE» или «EXCLUSIVE». Смотрите раздел [Управление транзакциями](https://python-all.ru/3.7/library/sqlite3.html#sqlite3-controlling-transactions) для более подробного объяснения.232233#### `in_transaction`234235[`True`](https://python-all.ru/3.7/library/constants.html#True), если транзакция активна (есть незафиксированные изменения), иначе [`False`](https://python-all.ru/3.7/library/constants.html#False). Атрибут только для чтения.236237Новое в версии 3.2.238239#### `cursor(factory=Cursor)`240241Метод cursor принимает один необязательный параметр *factory*. Если он указан, это должен быть вызываемый объект, возвращающий экземпляр [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor) или его подклассов.242243#### `commit()`244245Этот метод фиксирует текущую транзакцию. Если не вызвать этот метод, все изменения, сделанные после последнего вызова `commit()`, не будут видны из других подключений к базе данных. Если вы не видите данные, которые записали в базу, проверьте, не забыли ли вызвать этот метод.246247#### `rollback()`248249Этот метод откатывает все изменения в базе данных, сделанные после последнего вызова [`commit()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.commit).250251#### `close()`252253Это закрывает подключение к базе данных. Обратите внимание, что это не вызывает автоматически [`commit()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.commit). Если просто закрыть подключение к базе данных, не вызвав предварительно [`commit()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.commit), изменения будут потеряны!254255#### `execute(sql[, parameters])`256257Это нестандартное сокращение, которое создаёт объект курсора вызовом метода [`cursor()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.cursor), затем вызывает метод [`execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute) курсора с переданными *параметрами* и возвращает курсор.258259#### `executemany(sql[, parameters])`260261Это нестандартное сокращение, которое создаёт объект курсора вызовом метода [`cursor()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.cursor), затем вызывает метод [`executemany()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.executemany) курсора с переданными *параметрами* и возвращает курсор.262263#### `executescript(sql_script)`264265Это нестандартное сокращение, которое создаёт объект курсора вызовом метода [`cursor()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.cursor), затем вызывает метод [`executescript()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.executescript) курсора с переданным *sql\_script* и возвращает курсор.266267#### `create_function(name, num_params, func)`268269Создаёт пользовательскую функцию, которую затем можно использовать в SQL-выражениях под именем функции *name*. *num\_params* – количество параметров, которые принимает функция (если *num\_params* равно -1, функция может принимать любое количество аргументов), а *func* – это вызываемый объект Python, который вызывается как SQL-функция.270271Функция может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и `None`.272273Пример:274275```python276import sqlite3277import hashlib278279def md5sum(t):280 return hashlib.md5(t).hexdigest()281282con = sqlite3.connect(":memory:")283con.create_function("md5", 1, md5sum)284cur = con.cursor()285cur.execute("select md5(?)", (b"foo",))286print(cur.fetchone()[0])287288con.close()289```290291#### `create_aggregate(name, num_params, aggregate_class)`292293Создаёт пользовательскую агрегатную функцию.294295Класс агрегата должен реализовывать метод `step`, который принимает количество параметров *num\_params* (если *num\_params* равно -1, функция может принимать любое количество аргументов), и метод `finalize`, который возвращает окончательный результат агрегата.296297Метод `finalize` может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и `None`.298299Пример:300301```python302import sqlite3303304class MySum:305 def __init__(self):306 self.count = 0307308 def step(self, value):309 self.count += value310311 def finalize(self):312 return self.count313314con = sqlite3.connect(":memory:")315con.create_aggregate("mysum", 1, MySum)316cur = con.cursor()317cur.execute("create table test(i)")318cur.execute("insert into test(i) values (1)")319cur.execute("insert into test(i) values (2)")320cur.execute("select mysum(i) from test")321print(cur.fetchone()[0])322323con.close()324```325326#### `create_collation(name, callable)`327328Создаёт collation с указанными *name* и *callable*. Вызываемый объект будет получать два строковых аргумента. Он должен возвращать -1, если первый меньше второго, 0, если они равны, и 1, если первый больше второго. Обратите внимание, что это управляет сортировкой (ORDER BY в SQL), поэтому сравнения не влияют на другие операции SQL.329330Обратите внимание, что вызываемый объект будет получать свои параметры в виде байтовых строк Python, которые обычно закодированы в UTF-8.331332Следующий пример показывает пользовательскую коллацию, которая сортирует «в обратном порядке»:333334```python335import sqlite3336337def collate_reverse(string1, string2):338 if string1 == string2:339 return 0340 elif string1 < string2:341 return 1342 else:343 return -1344345con = sqlite3.connect(":memory:")346con.create_collation("reverse", collate_reverse)347348cur = con.cursor()349cur.execute("create table test(x)")350cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])351cur.execute("select x from test order by x collate reverse")352for row in cur:353 print(row)354con.close()355```356357Чтобы удалить коллацию, вызовите `create_collation` с `None` в качестве вызываемого объекта:358359```python360con.create_collation("reverse", None)361```362363#### `interrupt()`364365Этот метод можно вызвать из другого потока, чтобы прервать любые запросы, которые могут выполняться в подключении. Запрос будет прерван, а вызывающий код получит исключение.366367#### `set_authorizer(authorizer_callback)`368369Эта процедура регистрирует колбэк. Колбэк вызывается при каждой попытке доступа к столбцу таблицы в базе данных. Колбэк должен возвращать `SQLITE_OK`, если доступ разрешён, `SQLITE_DENY`, если весь SQL-запрос должен быть прерван с ошибкой, и `SQLITE_IGNORE`, если столбец должен рассматриваться как значение NULL. Эти константы доступны в модуле [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3).370371Первый аргумент колбэка указывает, какой тип операции требуется авторизовать. Второй и третий аргументы будут аргументами или [`None`](https://python-all.ru/3.7/library/constants.html#None) в зависимости от первого аргумента. Четвёртый аргумент – имя базы данных («main», «temp» и т.д.), если применимо. Пятый аргумент – имя самого внутреннего триггера или представления, ответственного за попытку доступа, или [`None`](https://python-all.ru/3.7/library/constants.html#None), если эта попытка доступа происходит непосредственно из входного SQL-кода.372373Обратитесь к документации SQLite за возможными значениями первого аргумента и значением второго и третьего аргументов в зависимости от первого. Все необходимые константы доступны в модуле [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3).374375#### `set_progress_handler(handler, n)`376377Эта процедура регистрирует колбэк. Колбэк вызывается каждые *n* инструкций виртуальной машины SQLite. Это полезно, если требуется получать вызовы от SQLite во время длительных операций, например для обновления графического интерфейса.378379Чтобы очистить ранее установленный обработчик прогресса, вызовите метод с [`None`](https://python-all.ru/3.7/library/constants.html#None) для *handler*.380381Возврат ненулевого значения из функции-обработчика завершит выполняющийся запрос и вызовет исключение [`OperationalError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.OperationalError).382383#### `set_trace_callback(trace_callback)`384385Регистрирует *trace\_callback*, который будет вызываться для каждого SQL-выражения, фактически выполняемого серверной частью SQLite.386387Единственный аргумент, передаваемый колбэку, – это выполняемый оператор (в виде строки). Возвращаемое значение колбэка игнорируется. Обратите внимание, что бэкенд выполняет не только операторы, переданные методам [`Cursor.execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute). Другие источники включают управление транзакциями модуля Python и выполнение триггеров, определённых в текущей базе данных.388389Передача [`None`](https://python-all.ru/3.7/library/constants.html#None) в качестве *trace\_callback* отключает трассировочный колбэк.390391Новое в версии 3.3.392393#### `enable_load_extension(enabled)`394395Эта процедура разрешает или запрещает механизму SQLite загружать расширения SQLite из разделяемых библиотек. Расширения SQLite могут определять новые функции, агрегатные функции или целые реализации виртуальных таблиц. Одним из известных расширений является расширение полнотекстового поиска, распространяемое с SQLite.396397Загружаемые расширения по умолчанию отключены. См. [1](https://python-all.ru/3.7/library/sqlite3.html#f1).398399Новое в версии 3.2.400401```python402import sqlite3403404con = sqlite3.connect(":memory:")405406# включить загрузку расширений407con.enable_load_extension(True)408409# Загрузить расширение полнотекстового поиска.410con.execute("select load_extension('./fts3.so')")411412# в качестве альтернативы можно загрузить расширение с помощью вызова API:413# con.load_extension("./fts3.so")414415# отключить загрузку расширения снова416con.enable_load_extension(False)417418# пример из вики SQLite419con.execute("create virtual table recipe using fts3(name, ingredients)")420con.executescript("""421 insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');422 insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');423 insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');424 insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');425 """)426for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):427 print(row)428429con.close()430```431432#### `load_extension(path)`433434Эта процедура загружает расширение SQLite из разделяемой библиотеки. Перед использованием этой процедуры необходимо включить загрузку расширений с помощью [`enable_load_extension()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.enable_load_extension).435436Загружаемые расширения по умолчанию отключены. См. [1](https://python-all.ru/3.7/library/sqlite3.html#f1).437438Новое в версии 3.2.439440#### `row_factory`441442Этот атрибут можно заменить на вызываемый объект, который принимает курсор и исходную строку в виде кортежа и возвращает реальную результирующую строку. Таким образом можно реализовать более продвинутые способы возврата результатов, например возврат объекта, который также может обращаться к столбцам по имени.443444Пример:445446```python447import sqlite3448449def dict_factory(cursor, row):450 d = {}451 for idx, col in enumerate(cursor.description):452 d[col[0]] = row[idx]453 return d454455con = sqlite3.connect(":memory:")456con.row_factory = dict_factory457cur = con.cursor()458cur.execute("select 1 as a")459print(cur.fetchone()["a"])460461con.close()462```463464Если возврата кортежа недостаточно и требуется доступ к столбцам по имени, рассмотрите возможность установки [`row_factory`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.row_factory) в высокооптимизированный тип [`sqlite3.Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row). [`Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row) обеспечивает как доступ по индексу, так и регистронезависимый доступ по имени с почти нулевыми накладными расходами памяти. Вероятно, это будет лучше, чем собственное решение на основе словаря или даже на основе db\_row.465466#### `text_factory`467468С помощью этого атрибута можно управлять тем, какие объекты возвращаются для типа данных `TEXT`. По умолчанию этот атрибут имеет значение [`str`](https://python-all.ru/3.7/library/stdtypes.html#str), и модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) возвращает объекты Unicode для `TEXT`. Если вместо этого нужно возвращать байтовые строки, можно установить значение [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes).469470Также можно установить его в любой другой вызываемый объект, принимающий единственный параметр – байтовую строку и возвращающий результирующий объект.471472См. следующий пример для иллюстрации:473474```python475import sqlite3476477con = sqlite3.connect(":memory:")478cur = con.cursor()479480AUSTRIA = "\xd6sterreich"481482# по умолчанию строки возвращаются как Unicode483cur.execute("select ?", (AUSTRIA,))484row = cur.fetchone()485assert row[0] == AUSTRIA486487# но можно заставить sqlite3 всегда возвращать байтовые строки...488con.text_factory = bytes489cur.execute("select ?", (AUSTRIA,))490row = cur.fetchone()491assert type(row[0]) is bytes492# байтовые строки будут в кодировке UTF-8, если только в базу не попал мусор493# база данных...494assert row[0] == AUSTRIA.encode("utf-8")495496# можно также реализовать собственный text_factory...497# здесь реализован такой, который добавляет "foo" ко всем строкам498con.text_factory = lambda x: x.decode("utf-8") + "foo"499cur.execute("select ?", ("bar",))500row = cur.fetchone()501assert row[0] == "barfoo"502503con.close()504```505506#### `total_changes`507508Возвращает общее количество строк базы данных, которые были изменены, вставлены или удалены с момента открытия подключения к базе данных.509510#### `iterdump()`511512Возвращает итератор для дампа базы данных в текстовом формате SQL. Полезно при сохранении базы данных в памяти для последующего восстановления. Эта функция предоставляет те же возможности, что и команда `.dump` в оболочке **sqlite3**.513514Пример:515516```python517# Преобразовать файл existing_db.db в SQL-дамп dump.sql518import sqlite3519520con = sqlite3.connect('existing_db.db')521with open('dump.sql', 'w') as f:522 for line in con.iterdump():523 f.write('%s\n' % line)524con.close()525```526527#### `backup(target, *, pages=0, progress=None, name="main", sleep=0.250)`528529Этот метод создает резервную копию базы данных SQLite даже во время её использования другими клиентами или одновременно тем же подключением. Копия будет записана в обязательный аргумент *target*, который должен быть другим экземпляром [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection).530531По умолчанию, или когда *pages* равен `0` или отрицательному целому, вся база данных копируется за один шаг; в противном случае метод выполняет цикл, копируя до *pages* страниц за раз.532533Если указан *progress*, он должен быть либо `None`, либо вызываемым объектом, который будет выполняться на каждой итерации с тремя целочисленными аргументами: *status* последней итерации, *remaining* количество страниц, оставшихся для копирования, и *total* общее количество страниц.534535Аргумент *name* задаёт имя базы данных, которая будет скопирована: это должна быть строка, содержащая либо `"main"` (по умолчанию) для основной базы данных, `"temp"` для временной базы данных, либо имя, указанное после ключевого слова `AS` в выражении `ATTACH DATABASE` для присоединённой базы данных.536537Аргумент *sleep* задаёт количество секунд ожидания между последовательными попытками резервного копирования оставшихся страниц; может быть указан как целое или число с плавающей запятой.538539Пример 1: копирование существующей базы данных в другую:540541```python542import sqlite3543544def progress(status, remaining, total):545 print(f'Copied {total-remaining} of {total} pages...')546547con = sqlite3.connect('existing_db.db')548bck = sqlite3.connect('backup.db')549with bck:550 con.backup(bck, pages=1, progress=progress)551bck.close()552con.close()553```554555Пример 2: копирование существующей базы данных во временную копию:556557```python558import sqlite3559560source = sqlite3.connect('existing_db.db')561dest = sqlite3.connect(':memory:')562source.backup(dest)563```564565Доступность: SQLite 3.6.11 или выше566567Добавлено в версии 3.7.568569## Объекты курсора570571#### `class sqlite3.Cursor`572573Экземпляр [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor) имеет следующие атрибуты и методы.574575#### `execute(sql[, parameters])`576577Выполняет SQL-выражение. SQL-выражение может быть параметризованным (т. е. с использованием плейсхолдеров вместо литералов SQL). Модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) поддерживает два вида плейсхолдеров: вопросительные знаки (стиль qmark) и именованные плейсхолдеры (именованный стиль).578579Вот пример обоих стилей:580581```python582import sqlite3583584con = sqlite3.connect(":memory:")585cur = con.cursor()586cur.execute("create table people (name_last, age)")587588who = "Yeltsin"589age = 72590591# Это стиль qmark:592cur.execute("insert into people values (?, ?)", (who, age))593594# А это именованный стиль:595cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})596597print(cur.fetchone())598599con.close()600```601602[`execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute) выполняет только одно SQL-выражение. При попытке выполнить с его помощью несколько выражений будет вызвано исключение [`Warning`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Warning). Используйте [`executescript()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.executescript), если нужно выполнить несколько SQL-выражений одним вызовом.603604#### `executemany(sql, seq_of_parameters)`605606Выполняет SQL-команду для всех последовательностей параметров или отображений, найденных в последовательности *seq\_of\_parameters*. Модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) также позволяет использовать [итератор](https://python-all.ru/3.7/glossary.html#term-iterator), возвращающий параметры, вместо последовательности.607608```python609import sqlite3610611class IterChars:612 def __init__(self):613 self.count = ord('a')614615 def __iter__(self):616 return self617618 def __next__(self):619 if self.count > ord('z'):620 raise StopIteration621 self.count += 1622 return (chr(self.count - 1),) # это кортеж из одного элемента623624con = sqlite3.connect(":memory:")625cur = con.cursor()626cur.execute("create table characters(c)")627628theIter = IterChars()629cur.executemany("insert into characters(c) values (?)", theIter)630631cur.execute("select c from characters")632print(cur.fetchall())633634con.close()635```636637Вот более короткий пример с использованием [генератора](https://python-all.ru/3.7/glossary.html#term-generator):638639```python640import sqlite3641import string642643def char_generator():644 for c in string.ascii_lowercase:645 yield (c,)646647con = sqlite3.connect(":memory:")648cur = con.cursor()649cur.execute("create table characters(c)")650651cur.executemany("insert into characters(c) values (?)", char_generator())652653cur.execute("select c from characters")654print(cur.fetchall())655656con.close()657```658659#### `executescript(sql_script)`660661Это нестандартный удобный метод для выполнения нескольких SQL-выражений за один раз. Сначала он выполняет оператор `COMMIT`, а затем выполняет SQL-скрипт, переданный в качестве параметра.662663*sql\_script* может быть экземпляром [`str`](https://python-all.ru/3.7/library/stdtypes.html#str).664665Пример:666667```python668import sqlite3669670con = sqlite3.connect(":memory:")671cur = con.cursor()672cur.executescript("""673 create table person(674 firstname,675 lastname,676 age677 );678679 create table book(680 title,681 author,682 published683 );684685 insert into book(title, author, published)686 values (687 'Dirk Gently''s Holistic Detective Agency',688 'Douglas Adams',689 1987690 );691 """)692con.close()693```694695#### `fetchone()`696697Извлекает следующую строку результата запроса, возвращая одну последовательность или [`None`](https://python-all.ru/3.7/library/constants.html#None), если данные закончились.698699#### `fetchmany(size=cursor.arraysize)`700701Извлекает следующий набор строк результата запроса, возвращая список. Пустой список возвращается, когда строк больше нет.702703Количество строк, извлекаемых за один вызов, задаётся параметром *size*. Если он не указан, количество строк определяется атрибутом arraysize курсора. Метод должен пытаться извлечь столько строк, сколько указано параметром size. Если это невозможно из-за того, что указанное количество строк недоступно, может быть возвращено меньше строк.704705Обратите внимание, что параметр *size* связан с производительностью. Для оптимальной производительности обычно лучше использовать атрибут arraysize. Если используется параметр *size*, рекомендуется сохранять одно и то же значение от одного вызова [`fetchmany()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.fetchmany) к следующему.706707#### `fetchall()`708709Извлекает все (оставшиеся) строки результата запроса, возвращая список. Обратите внимание, что атрибут arraysize курсора может влиять на производительность этой операции. Пустой список возвращается, если строк нет.710711#### `close()`712713Закрывает курсор сейчас (а не при вызове `__del__`).714715Курсор станет непригодным к использованию; будет выброшено исключение [`ProgrammingError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.ProgrammingError) при любой попытке выполнить операцию с курсором.716717#### `rowcount`718719Хотя класс [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor) модуля [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) реализует этот атрибут, собственная поддержка определения «затронутых строк»/«выбранных строк» в движке базы данных работает непредсказуемо.720721Для выражений [`executemany()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.executemany) количество изменений суммируется в [`rowcount`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.rowcount).722723В соответствии со спецификацией Python DB API, атрибут [`rowcount`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.rowcount) «равен -1, если над курсором не выполнялось `executeXX()` или количество строк последней операции не может быть определено интерфейсом». Это включает выражения `SELECT`, потому что количество строк, полученных запросом, нельзя определить, пока не будут извлечены все строки.724725В SQLite версий до 3.6.5 [`rowcount`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.rowcount) устанавливается в 0, если выполнить `DELETE FROM table` без условия.726727#### `lastrowid`728729Этот атрибут только для чтения возвращает rowid последней измененной строки. Он устанавливается только при выполнении оператора `INSERT` или `REPLACE` с использованием метода [`execute()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.execute). Для операций, отличных от `INSERT` или `REPLACE`, или при вызове [`executemany()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.executemany), [`lastrowid`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.lastrowid) устанавливается в [`None`](https://python-all.ru/3.7/library/constants.html#None).730731Если оператору `INSERT` или `REPLACE` не удалось выполнить вставку, возвращается rowid предыдущей успешной вставки.732733Изменено в версии 3.6: Добавлена поддержка оператора `REPLACE`.734735#### `arraysize`736737Атрибут чтения/записи, управляющий количеством строк, возвращаемых [`fetchmany()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.fetchmany). Значение по умолчанию – 1, то есть при каждом вызове будет извлечена одна строка.738739#### `description`740741Этот атрибут только для чтения содержит имена столбцов последнего запроса. Для совместимости с Python DB API он возвращает 7-кортеж для каждого столбца, где последние шесть элементов каждого кортежа равны [`None`](https://python-all.ru/3.7/library/constants.html#None).742743Он также устанавливается для операторов `SELECT`, не имеющих подходящих строк.744745#### `connection`746747Этот атрибут только для чтения предоставляет [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection) базы данных SQLite, используемый объектом [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor). Объект [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor), созданный вызовом [`con.cursor()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.cursor), будет иметь атрибут [`connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.connection), ссылающийся на *con*:748749```python750>>> con = sqlite3.connect(":memory:")751>>> cur = con.cursor()752>>> cur.connection == con753True754```755756## Объекты строк757758#### `class sqlite3.Row`759760Экземпляр [`Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row) служит высокооптимизированной [`row_factory`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.row_factory) для объектов [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection). Он старается имитировать кортеж в большинстве своих возможностей.761762Он поддерживает доступ по имени столбца и индексу, итерацию, представление, проверку равенства и [`len()`](https://python-all.ru/3.7/library/functions.html#len).763764Если два объекта [`Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row) имеют одинаковые столбцы и их члены равны, они считаются равными.765766#### `keys()`767768Этот метод возвращает список имён столбцов. Сразу после запроса это первый элемент каждого кортежа в [`Cursor.description`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor.description).769770Изменено в версии 3.5: Добавлена поддержка срезов.771772Предположим, мы инициализируем таблицу, как в приведённом выше примере:773774```python775conn = sqlite3.connect(":memory:")776c = conn.cursor()777c.execute('''create table stocks778(date text, trans text, symbol text,779 qty real, price real)''')780c.execute("""insert into stocks781 values ('2006-01-05','BUY','RHAT',100,35.14)""")782conn.commit()783c.close()784```785786Теперь подключаем [`Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row):787788```python789>>> conn.row_factory = sqlite3.Row790>>> c = conn.cursor()791>>> c.execute('select * from stocks')792<sqlite3.Cursor object at 0x7f4e7dd8fa80>793>>> r = c.fetchone()794>>> type(r)795<class 'sqlite3.Row'>796>>> tuple(r)797('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)798>>> len(r)7995800>>> r[2]801'RHAT'802>>> r.keys()803['date', 'trans', 'symbol', 'qty', 'price']804>>> r['qty']805100.0806>>> for member in r:807... print(member)808...8092006-01-05810BUY811RHAT812100.081335.14814```815816## Исключения817818#### `exception sqlite3.Warning`819820Подкласс [`Exception`](https://python-all.ru/3.7/library/exceptions.html#Exception).821822#### `exception sqlite3.Error`823824Базовый класс остальных исключений в этом модуле. Он является подклассом [`Exception`](https://python-all.ru/3.7/library/exceptions.html#Exception).825826#### `exception sqlite3.DatabaseError`827828Исключение, вызываемое для ошибок, связанных с базой данных.829830#### `exception sqlite3.IntegrityError`831832Исключение возникает при нарушении реляционной целостности базы данных, например, при неудачной проверке внешнего ключа. Оно является подклассом [`DatabaseError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.DatabaseError).833834#### `exception sqlite3.ProgrammingError`835836Исключение вызывается при ошибках программирования, например, таблица не найдена или уже существует, синтаксическая ошибка в SQL-запросе, указано неверное количество параметров и т.д. Является подклассом [`DatabaseError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.DatabaseError).837838#### `exception sqlite3.OperationalError`839840Исключение вызывается для ошибок, связанных с работой базы данных и не обязательно находящихся под контролем программиста, например, неожиданное отключение, не найден источник данных, транзакция не могла быть обработана, и т.д. Является подклассом [`DatabaseError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.DatabaseError).841842#### `exception sqlite3.NotSupportedError`843844Исключение вызывается, если используется метод или API базы данных, который не поддерживается базой данных, например, вызов метода [`rollback()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.rollback) для соединения, которое не поддерживает транзакции или имеет транзакции отключены. Является подклассом [`DatabaseError`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.DatabaseError).845846## Типы SQLite и Python847848### Введение849850SQLite изначально поддерживает следующие типы: `NULL`, `INTEGER`, `REAL`, `TEXT`, `BLOB`.851852Следующие типы Python можно передавать в SQLite без каких-либо проблем:853854| Тип Python | Тип SQLite |855| --- | --- |856| [`None`](https://python-all.ru/3.7/library/constants.html#None) | `NULL` |857| [`int`](https://python-all.ru/3.7/library/functions.html#int) | `INTEGER` |858| [`float`](https://python-all.ru/3.7/library/functions.html#float) | `REAL` |859| [`str`](https://python-all.ru/3.7/library/stdtypes.html#str) | `TEXT` |860| [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes) | `BLOB` |861862Так по умолчанию типы SQLite преобразуются в типы Python:863864| Тип SQLite | Тип Python |865| --- | --- |866| `NULL` | [`None`](https://python-all.ru/3.7/library/constants.html#None) |867| `INTEGER` | [`int`](https://python-all.ru/3.7/library/functions.html#int) |868| `REAL` | [`float`](https://python-all.ru/3.7/library/functions.html#float) |869| `TEXT` | зависит от [`text_factory`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.text_factory), по умолчанию [`str`](https://python-all.ru/3.7/library/stdtypes.html#str) |870| `BLOB` | [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes) |871872Система типов модуля [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) расширяема двумя способами: можно хранить дополнительные типы Python в базе данных SQLite с помощью адаптации объектов, а также можно позволить модулю [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) преобразовывать типы SQLite в различные типы Python с помощью конвертеров.873874### Использование адаптеров для хранения дополнительных типов Python в базах данных SQLite875876Как описывалось ранее, SQLite изначально поддерживает только ограниченный набор типов. Чтобы использовать другие типы Python с SQLite, необходимо **адаптировать** их к одному из поддерживаемых модулем sqlite3 типов для SQLite: NoneType, int, float, str, bytes.877878Существует два способа разрешить модулю [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) адаптировать пользовательский тип Python к одному из поддерживаемых.879880#### Адаптация объекта самого себя881882Это хороший подход, если вы пишете класс сами. Предположим, у вас есть такой класс:883884```python885class Point:886 def __init__(self, x, y):887 self.x, self.y = x, y888```889890Теперь нужно сохранить точку в одном столбце SQLite. Сначала нужно выбрать один из поддерживаемых типов для представления точки. Давайте просто используем str и разделим координаты точкой с запятой. Затем нужно определить в классе метод `__conform__(self, protocol)`, который должен возвращать преобразованное значение. Параметр *протокол* будет равен `PrepareProtocol`.891892```python893import sqlite3894895class Point:896 def __init__(self, x, y):897 self.x, self.y = x, y898899 def __conform__(self, protocol):900 if protocol is sqlite3.PrepareProtocol:901 return "%f;%f" % (self.x, self.y)902903con = sqlite3.connect(":memory:")904cur = con.cursor()905906p = Point(4.0, -3.2)907cur.execute("select ?", (p,))908print(cur.fetchone()[0])909910con.close()911```912913#### Регистрация вызываемого адаптера914915Другой вариант – создать функцию, которая преобразует тип в строковое представление, и зарегистрировать её с помощью [`register_adapter()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.register_adapter).916917```python918import sqlite3919920class Point:921 def __init__(self, x, y):922 self.x, self.y = x, y923924def adapt_point(point):925 return "%f;%f" % (point.x, point.y)926927sqlite3.register_adapter(Point, adapt_point)928929con = sqlite3.connect(":memory:")930cur = con.cursor()931932p = Point(4.0, -3.2)933cur.execute("select ?", (p,))934print(cur.fetchone()[0])935936con.close()937```938939Модуль [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) имеет два адаптера по умолчанию для встроенных типов Python [`datetime.date`](https://python-all.ru/3.7/library/datetime.html#datetime.date) и [`datetime.datetime`](https://python-all.ru/3.7/library/datetime.html#datetime.datetime). Теперь предположим, что мы хотим сохранить объекты [`datetime.datetime`](https://python-all.ru/3.7/library/datetime.html#datetime.datetime) не в формате ISO, а в виде временной метки Unix.940941```python942import sqlite3943import datetime944import time945946def adapt_datetime(ts):947 return time.mktime(ts.timetuple())948949sqlite3.register_adapter(datetime.datetime, adapt_datetime)950951con = sqlite3.connect(":memory:")952cur = con.cursor()953954now = datetime.datetime.now()955cur.execute("select ?", (now,))956print(cur.fetchone()[0])957958con.close()959```960961### Преобразование значений SQLite в пользовательские типы Python962963Написание адаптера позволяет отправлять пользовательские типы Python в SQLite. Но чтобы сделать это действительно полезным, нужно обеспечить обратное преобразование из SQLite в Python.964965Вступают конвертеры.966967Вернемся к классу `Point`. Мы сохраняли координаты x и y, разделенные точкой с запятой, в виде строк в SQLite.968969Сначала определим функцию-конвертер, которая принимает строку в качестве параметра и создает из нее объект `Point`.970971> **Примечание**972>973> Функции-конвертеры **всегда** вызываются с объектом [`bytes`](https://python-all.ru/3.7/library/stdtypes.html#bytes), независимо от того, с каким типом данных значение было отправлено в SQLite.974975```python976def convert_point(s):977 x, y = map(float, s.split(b";"))978 return Point(x, y)979```980981Теперь нужно сообщить модулю [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3), что выбираемые из базы данные на самом деле являются точкой. Есть два способа сделать это:982983- Неявно, через объявленный тип984- Явно, по имени колонки985986Оба способа описаны в разделе [Функции и константы модуля](https://python-all.ru/3.7/library/sqlite3.html#sqlite3-module-contents), в записях для констант [`PARSE_DECLTYPES`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.PARSE_COLNAMES).987988Следующий пример иллюстрирует оба подхода.989990```python991import sqlite3992993class Point:994 def __init__(self, x, y):995 self.x, self.y = x, y996997 def __repr__(self):998 return "(%f;%f)" % (self.x, self.y)9991000def adapt_point(point):1001 return ("%f;%f" % (point.x, point.y)).encode('ascii')10021003def convert_point(s):1004 x, y = list(map(float, s.split(b";")))1005 return Point(x, y)10061007# Зарегистрировать адаптер1008sqlite3.register_adapter(Point, adapt_point)10091010# Зарегистрировать конвертер1011sqlite3.register_converter("point", convert_point)10121013p = Point(4.0, -3.2)10141015#########################1016# 1) Использование объявленных типов1017con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)1018cur = con.cursor()1019cur.execute("create table test(p point)")10201021cur.execute("insert into test(p) values (?)", (p,))1022cur.execute("select p from test")1023print("with declared types:", cur.fetchone()[0])1024cur.close()1025con.close()10261027#######################1028# 1) Использование имён столбцов1029con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)1030cur = con.cursor()1031cur.execute("create table test(p)")10321033cur.execute("insert into test(p) values (?)", (p,))1034cur.execute('select p as "p [point]" from test')1035print("with column names:", cur.fetchone()[0])1036cur.close()1037con.close()1038```10391040### Адаптеры и преобразователи по умолчанию10411042В модуле datetime есть адаптеры по умолчанию для типов date и datetime. Они отправляются в SQLite как даты/временные метки в формате ISO.10431044Преобразователи по умолчанию зарегистрированы под именем «date» для [`datetime.date`](https://python-all.ru/3.7/library/datetime.html#datetime.date) и под именем «timestamp» для [`datetime.datetime`](https://python-all.ru/3.7/library/datetime.html#datetime.datetime).10451046Таким образом, в большинстве случаев можно использовать даты и временные метки из Python без лишних усилий. Формат адаптеров также совместим с экспериментальными функциями даты/времени SQLite.10471048Следующий пример демонстрирует это.10491050```python1051import sqlite31052import datetime10531054con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)1055cur = con.cursor()1056cur.execute("create table test(d date, ts timestamp)")10571058today = datetime.date.today()1059now = datetime.datetime.now()10601061cur.execute("insert into test(d, ts) values (?, ?)", (today, now))1062cur.execute("select d, ts from test")1063row = cur.fetchone()1064print(today, "=>", row[0], type(row[0]))1065print(now, "=>", row[1], type(row[1]))10661067cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')1068row = cur.fetchone()1069print("current_date", row[0], type(row[0]))1070print("current_timestamp", row[1], type(row[1]))10711072con.close()1073```10741075Если временная метка, хранящаяся в SQLite, имеет дробную часть длиннее 6 знаков, её значение будет усечено до микросекундной точности преобразователем временных меток.10761077## Управление транзакциями10781079Лежащая в основе библиотека `sqlite3` по умолчанию работает в режиме `autocommit`, а модуль Python [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) по умолчанию – нет.10801081Режим `autocommit` означает, что операторы, изменяющие базу данных, вступают в силу немедленно. Оператор `BEGIN` или `SAVEPOINT` отключает режим `autocommit`, а оператор `COMMIT`, `ROLLBACK` или `RELEASE`, завершающий внешнюю транзакцию, снова включает режим `autocommit`.10821083Модуль Python [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) по умолчанию неявно выполняет оператор `BEGIN` перед оператором языка модификации данных (DML) (т.е. `INSERT`/`UPDATE`/`DELETE`/`REPLACE`).10841085Можно управлять тем, какие операторы `BEGIN` [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) выполняет неявно, с помощью параметра *isolation\_level* вызова [`connect()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.connect), или через свойство `isolation_level` соединений. Если не указывать *isolation\_level*, используется простой `BEGIN`, что eквивалентно указанию `DEFERRED`. Другие возможные значения: `IMMEDIATE` и `EXCLUSIVE`.10861087Можно отключить неявное управление транзакциями модуля [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3), установив `isolation_level` в `None`. При этом лежащая в основе библиотека `sqlite3` продолжит работать в режиме `autocommit`. После этого можно полностью управлять состоянием транзакции, явно выполняя операторы `BEGIN`, `ROLLBACK`, `SAVEPOINT` и `RELEASE` в коде.10881089Изменено в версии 3.6: [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) ранее неявно фиксировал открытую транзакцию перед DDL операторами. Теперь это не так.10901091## Эффективное использование [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3)10921093### Использование сокращенных методов10941095Используя нестандартные методы `execute()`, `executemany()` и `executescript()` объекта [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection), код можно писать более кратко, поскольку не нужно явно создавать (часто излишние) объекты [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor). Вместо этого объекты [`Cursor`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Cursor) создаются неявно, и эти сокращенные методы возвращают объекты курсора. Таким образом, можно выполнить оператор `SELECT` и итерироваться по нему напрямую, используя всего один вызов объекта [`Connection`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection).10961097```python1098import sqlite310991100persons = [1101 ("Hugo", "Boss"),1102 ("Calvin", "Klein")1103 ]11041105con = sqlite3.connect(":memory:")11061107# Создать таблицу1108con.execute("create table person(firstname, lastname)")11091110# Заполнить таблицу1111con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)11121113# Выводит содержимое таблицы.1114for row in con.execute("select firstname, lastname from person"):1115 print(row)11161117print("I just deleted", con.execute("delete from person").rowcount, "rows")11181119# close не является методом-ярлыком и не вызывается автоматически,1120# поэтому объект соединения следует закрывать вручную.1121con.close()1122```11231124### Доступ к столбцам по имени вместо индекса11251126Одна из полезных возможностей модуля [`sqlite3`](https://python-all.ru/3.7/library/sqlite3.html#module-sqlite3) – встроенный класс [`sqlite3.Row`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Row), предназначенный для использования в качестве фабрики строк.11271128Строки, обёрнутые этим классом, можно получать как по индексу (как кортежи), так и по имени без учёта регистра:11291130```python1131import sqlite311321133con = sqlite3.connect(":memory:")1134con.row_factory = sqlite3.Row11351136cur = con.cursor()1137cur.execute("select 'John' as name, 42 as age")1138for row in cur:1139 assert row[0] == row["name"]1140 assert row["name"] == row["nAmE"]1141 assert row[1] == row["age"]1142 assert row[1] == row["AgE"]11431144con.close()1145```11461147### Использование соединения как менеджера контекста11481149Объекты соединения можно использовать как менеджеры контекста, которые автоматически фиксируют или откатывают транзакции. В случае исключения транзакция откатывается; в противном случае транзакция фиксируется:11501151```python1152import sqlite311531154con = sqlite3.connect(":memory:")1155con.execute("create table person (id integer primary key, firstname varchar unique)")11561157# При успешном выполнении con.commit() вызывается автоматически.1158with con:1159 con.execute("insert into person(firstname) values (?)", ("Joe",))11601161# con.rollback() вызывается после завершения блока with с исключением,1162# исключение все равно возбуждается, и его необходимо перехватить1163try:1164 with con:1165 con.execute("insert into person(firstname) values (?)", ("Joe",))1166except sqlite3.IntegrityError:1167 print("couldn't add Joe twice")11681169# Объект Connection, используемый как контекстный менеджер, только фиксирует или откатывает транзакции,1170# поэтому объект соединения следует закрывать вручную.1171con.close()1172```11731174## Распространённые проблемы11751176### Многопоточность11771178В старых версиях SQLite были проблемы с совместным использованием соединений между потоками. Именно поэтому модуль Python запрещает совместное использование соединений и курсоров между потоками. Если всё же попытаться это сделать, во время выполнения будет возбуждено исключение.11791180Единственное исключение – вызов метода [`interrupt()`](https://python-all.ru/3.7/library/sqlite3.html#sqlite3.Connection.interrupt), который имеет смысл вызывать только из другого потока.11811182Сноски11831184**1([1](https://python-all.ru/3.7/library/sqlite3.html#id1),[2](https://python-all.ru/3.7/library/sqlite3.html#id2))**11851186Модуль sqlite3 по умолчанию собирается без поддержки загружаемых расширений, поскольку на некоторых платформах (в частности, Mac OS X) библиотеки SQLite скомпилированы без этой возможности. Чтобы получить поддержку загружаемых расширений, необходимо передать параметр –enable-loadable-sqlite-extensions программе configure.1187