Документация Python неофициальный перевод

sqlite3.md

1039 строк · 68.3 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/library/sqlite3.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 12.6. [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) – DB-API 2.0 interface for SQLite databases89SQLite – это библиотека на C, которая предоставляет легковесную дисковую базу данных, не требующую отдельного серверного процесса, и позволяет обращаться к базе данных с помощью нестандартного варианта языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также можно создать прототип приложения на SQLite, а затем перенести код на более крупную базу данных, например PostgreSQL или Oracle.1011Модуль sqlite3 написан Герхардом Харингом. Он предоставляет SQL-интерфейс, соответствующий спецификации DB-API 2.0, описанной в [**PEP 249**](https://python-all.ru/3.4/library/sqlite3.html).1213Чтобы использовать модуль, сначала нужно создать объект [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection), представляющий базу данных. Здесь данные будут храниться в файле `example.db`:1415```python16import sqlite317conn = sqlite3.connect('example.db')18```1920Можно также указать специальное имя `:memory:`, чтобы создать базу данных в оперативной памяти.2122Когда у вас есть объект [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection), можно создать объект [`Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor) и вызывать его метод [`execute()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute) для выполнения SQL-команд:2324```python25c = conn.cursor()2627# Создать таблицу28c.execute('''CREATE TABLE stocks29             (date text, trans text, symbol text, qty real, price real)''')3031# Вставить строку данных32c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")3334# Сохранить (зафиксировать) изменения35conn.commit()3637# Также можно закрыть соединение, если работа с ним завершена.38# Все изменения должны быть зафиксированы, иначе они будут потеряны.39conn.close()40```4142Сохранённые данные являются постоянными и доступны в последующих сеансах:4344```python45import sqlite346conn = sqlite3.connect('example.db')47c = conn.cursor()48```4950Обычно в SQL-операциях нужно использовать значения из переменных Python. Не следует собирать запрос с помощью строковых операций Python, потому что это небезопасно: программа становится уязвимой для SQL-инъекций (см. [http://xkcd.com/327/](https://python-all.ru/3.4/library/sqlite3.html) – забавный пример того, что может пойти не так).5152Вместо этого используйте подстановку параметров DB-API. Поставьте `?` в качестве заполнителя там, где нужно использовать значение, а затем передайте кортеж значений вторым аргументом методу [`execute()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute) курсора. (В других модулях баз данных может использоваться другой заполнитель, например `%s` или `:1`.) Например:5354```python55# Никогда не делайте этого – это небезопасно!56symbol = 'RHAT'57c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)5859# Вместо этого сделайте так60t = ('RHAT',)61c.execute('SELECT * FROM stocks WHERE symbol=?', t)62print(c.fetchone())6364# Более крупный пример, вставляющий много записей за один раз65purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),66             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),67             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),68            ]69c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)70```7172Чтобы извлечь данные после выполнения оператора SELECT, можно либо рассматривать курсор как [*итератор*](https://python-all.ru/3.4/glossary.html#term-iterator), вызывать его метод [`fetchone()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.fetchone) для получения одной подходящей строки, либо вызвать [`fetchall()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.fetchall) для получения списка всех подходящих строк.7374В этом примере используется форма итератора:7576```python77>>> for row in c.execute('SELECT * FROM stocks ORDER BY price'):78        print(row)7980('2006-01-05', 'BUY', 'RHAT', 100, 35.14)81('2006-03-28', 'BUY', 'IBM', 1000, 45.0)82('2006-04-06', 'SELL', 'IBM', 500, 53.0)83('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)84```8586> **См. также**87>88> **[https://github.com/ghaering/pysqlite](https://python-all.ru/3.4/library/sqlite3.html)**89>90> Страница pysqlite – sqlite3 разрабатывается отдельно под названием «pysqlite».91>92> **[http://www.sqlite.org](https://python-all.ru/3.4/library/sqlite3.html)**93>94> Веб-страница SQLite; документация описывает синтаксис и доступные типы данных поддерживаемого диалекта SQL.95>96> **[http://www.w3schools.com/sql/](https://python-all.ru/3.4/library/sqlite3.html)**97>98> Учебные материалы, справочник и примеры для изучения синтаксиса SQL.99>100> **[**PEP 249**](https://python-all.ru/3.4/library/sqlite3.html) – спецификация API баз данных 2.0**101>102> PEP написан Марком-Андре Лембургом.103104## 12.6.1. Функции и константы модуля105106#### `sqlite3.version`107108Номер версии этого модуля в виде строки. Это не версия библиотеки SQLite.109110#### `sqlite3.version_info`111112Номер версии этого модуля в виде кортежа целых чисел. Это не версия библиотеки SQLite.113114#### `sqlite3.sqlite_version`115116Номер версии библиотеки SQLite времени выполнения в виде строки.117118#### `sqlite3.sqlite_version_info`119120Номер версии библиотеки SQLite времени выполнения в виде кортежа целых чисел.121122#### `sqlite3.PARSE_DECLTYPES`123124Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.connect).125126Если установить этот флаг, модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) будет анализировать объявленный тип для каждого возвращаемого столбца. Он извлечёт первое слово объявленного типа, например, для «integer primary key» извлечёт «integer», а для «number(10)» – «number». Затем для этого столбца будет выполнен поиск в словаре конвертеров и использована зарегистрированная для этого типа функция преобразования.127128#### `sqlite3.PARSE_COLNAMES`129130Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.connect).131132Если установить этот флаг, интерфейс SQLite будет анализировать имя столбца для каждого возвращаемого столбца. Он будет искать строку вида \[mytype\] в имени столбца и затем считать, что «mytype» – это тип столбца. Далее будет выполнена попытка найти запись «mytype» в словаре конвертеров и используется найденная функция преобразования для возврата значения. Имя столбца, полученное из [`Cursor.description`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.description), – это только первое слово имени столбца; то есть если в SQL используется что-то вроде `'as "x [datetime]"'`, то будет извлечено всё до первого пробела: имя столбца будет просто «x».133134#### `sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])`135136Открывает соединение с файлом базы данных SQLite *database*. Можно использовать `":memory:"`, чтобы открыть соединение с базой данных, расположенной в оперативной памяти, а не на диске.137138Когда к базе данных обращаются несколько соединений и один из процессов изменяет базу данных, база данных SQLite блокируется до завершения этой транзакции. Параметр *timeout* задаёт, как долго соединение должно ждать снятия блокировки, прежде чем возникнет исключение. Значение по умолчанию для параметра timeout – 5.0 (пять секунд).139140По поводу параметра *isolation\_level* обратитесь к свойству [`Connection.isolation_level`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.isolation_level) объектов [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection).141142SQLite изначально поддерживает только типы TEXT, INTEGER, REAL, BLOB и NULL. Если нужно использовать другие типы, потребуется добавить поддержку самостоятельно. Параметр *detect\_types* и использование собственных **конвертеров**, зарегистрированных с помощью функции уровня модуля [`register_converter()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.register_converter), позволяют легко это сделать.143144Параметр *detect\_types* по умолчанию равен 0 (т.е. выключен, определение типов отключено); его можно установить в любую комбинацию [`PARSE_DECLTYPES`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.PARSE_COLNAMES) для включения определения типов.145146По умолчанию модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) использует для вызова connect() свой класс [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection). Однако можно создать подкласс класса [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection) и заставить [`connect()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.connect) использовать ваш класс, передав его в параметре *factory*.147148Подробности см. в разделе [*Типы SQLite и Python*](https://python-all.ru/3.4/library/sqlite3.html#sqlite3-types) данного руководства.149150Модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) внутренне использует кеш операторов, чтобы избежать накладных расходов на разбор SQL. Если требуется явно задать количество операторов, кешируемых для соединения, можно установить параметр *cached\_statements*. Текущая реализация по умолчанию кеширует 100 операторов.151152Если *uri* равно true, *database* интерпретируется как URI. Это позволяет задавать параметры. Например, чтобы открыть базу данных в режиме только для чтения, можно использовать:153154```python155db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)156```157158Дополнительную информацию об этой возможности, включая список распознаваемых параметров, можно найти в [документации SQLite URI](https://python-all.ru/3.4/library/sqlite3.html).159160Изменено в версии 3.4: Добавлен параметр *uri*.161162#### `sqlite3.register_converter(typename, callable)`163164Регистрирует вызываемый объект для преобразования байтовой строки из базы данных в пользовательский тип Python. Этот вызываемый объект будет вызываться для всех значений базы данных, имеющих тип *typename*. О том, как работает определение типа, см. параметр *detect\_types* функции [`connect()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.connect). Обратите внимание, что регистр символов в *typename* и имени типа в запросе должны совпадать!165166#### `sqlite3.register_adapter(type, callable)`167168Регистрирует вызываемый объект для преобразования пользовательского типа Python *type* в один из поддерживаемых типов SQLite. Вызываемый объект *callable* принимает в качестве единственного параметра значение Python и должен возвращать значение одного из следующих типов: int, float, str или bytes.169170#### `sqlite3.complete_statement(sql)`171172Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если строка *sql* содержит одно или несколько полных SQL-выражений, завершённых точкой с запятой. При этом не проверяется синтаксическая корректность SQL – только отсутствие незакрытых строковых литералов и наличие точки с запятой в конце каждого выражения.173174Это можно использовать для создания оболочки для SQLite, как в следующем примере:175176```python177# Минимальная оболочка SQLite для экспериментов178179import sqlite3180181con = sqlite3.connect(":memory:")182con.isolation_level = None183cur = con.cursor()184185buffer = ""186187print("Enter your SQL commands to execute in sqlite3.")188print("Enter a blank line to exit.")189190while True:191    line = input()192    if line == "":193        break194    buffer += line195    if sqlite3.complete_statement(buffer):196        try:197            buffer = buffer.strip()198            cur.execute(buffer)199200            if buffer.lstrip().upper().startswith("SELECT"):201                print(cur.fetchall())202        except sqlite3.Error as e:203            print("An error occurred:", e.args[0])204        buffer = ""205206con.close()207```208209#### `sqlite3.enable_callback_tracebacks(flag)`210211По умолчанию трассировки не отображаются для пользовательских функций, агрегатов, преобразователей, колбэков авторизатора и т.д. Если нужно их отладить, можно вызвать эту функцию, установив *flag* в `True`. После этого трассировки от колбэков будут выводиться в `sys.stderr`. Чтобы снова отключить эту возможность, используйте [`False`](https://python-all.ru/3.4/library/constants.html#False).212213## 12.6.2. Объекты соединения214215#### `class sqlite3.Connection`216217Соединение с базой данных SQLite обладает следующими атрибутами и методами:218219#### `isolation_level`220221Получает или устанавливает текущий уровень изоляции. [`None`](https://python-all.ru/3.4/library/constants.html#None) для режима автокоммита или одно из значений «DEFERRED», «IMMEDIATE» или «EXCLUSIVE». Подробное объяснение приведено в разделе [*Управление транзакциями*](https://python-all.ru/3.4/library/sqlite3.html#sqlite3-controlling-transactions).222223#### `in_transaction`224225[`True`](https://python-all.ru/3.4/library/constants.html#True), если транзакция активна (есть незафиксированные изменения), и [`False`](https://python-all.ru/3.4/library/constants.html#False) в противном случае. Атрибут только для чтения.226227Новое в версии 3.2.228229#### `cursor([cursorClass])`230231Метод cursor принимает один необязательный параметр *cursorClass*. Если он указан, это должен быть пользовательский класс курсора, наследующий от [`sqlite3.Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor).232233#### `commit()`234235Этот метод фиксирует текущую транзакцию. Если его не вызвать, все изменения, сделанные после последнего вызова `commit()`, не будут видны из других подключений к базе данных. Если вы удивляетесь, почему не видите записанные данные, проверьте, не забыли ли вызвать этот метод.236237#### `rollback()`238239Этот метод откатывает все изменения в базе данных, сделанные после последнего вызова [`commit()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.commit).240241#### `close()`242243Этот метод закрывает подключение к базе данных. Обратите внимание, что он не вызывает автоматически [`commit()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.commit). Если просто закрыть подключение без предварительного вызова [`commit()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.commit), изменения будут потеряны!244245#### `execute(sql[, parameters])`246247Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`execute`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute) этого курсора с переданными параметрами.248249#### `executemany(sql[, parameters])`250251Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`executemany`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.executemany) этого курсора с переданными параметрами.252253#### `executescript(sql_script)`254255Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`executescript`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.executescript) этого курсора с переданными параметрами.256257#### `create_function(name, num_params, func)`258259Создаёт пользовательскую функцию, которую затем можно использовать в SQL-выражениях под именем *name*. *num\_params* – количество параметров, принимаемых функцией, а *func* – вызываемый объект Python, который будет вызываться как SQL-функция.260261Функция может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и None.262263Пример:264265```python266import sqlite3267import hashlib268269def md5sum(t):270    return hashlib.md5(t).hexdigest()271272con = sqlite3.connect(":memory:")273con.create_function("md5", 1, md5sum)274cur = con.cursor()275cur.execute("select md5(?)", (b"foo",))276print(cur.fetchone()[0])277```278279#### `create_aggregate(name, num_params, aggregate_class)`280281Создаёт пользовательскую агрегатную функцию.282283Класс агрегатной функции должен реализовывать метод `step`, который принимает количество параметров *num\_params*, и метод `finalize`, который возвращает конечный результат агрегации.284285Метод `finalize` может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и None.286287Пример:288289```python290import sqlite3291292class MySum:293    def __init__(self):294        self.count = 0295296    def step(self, value):297        self.count += value298299    def finalize(self):300        return self.count301302con = sqlite3.connect(":memory:")303con.create_aggregate("mysum", 1, MySum)304cur = con.cursor()305cur.execute("create table test(i)")306cur.execute("insert into test(i) values (1)")307cur.execute("insert into test(i) values (2)")308cur.execute("select mysum(i) from test")309print(cur.fetchone()[0])310```311312#### `create_collation(name, callable)`313314Создаёт collation с указанными *name* и *callable*. Вызываемый объект будет получать два строковых аргумента. Он должен возвращать -1, если первый меньше второго, 0, если они равны, и 1, если первый больше второго. Обратите внимание, что это управляет сортировкой (ORDER BY в SQL), поэтому сравнения не влияют на другие операции SQL.315316Обратите внимание, что вызываемый объект будет получать свои параметры в виде байтовых строк Python, которые обычно закодированы в UTF-8.317318Следующий пример показывает пользовательскую коллацию, которая сортирует «в обратном порядке»:319320```python321import sqlite3322323def collate_reverse(string1, string2):324    if string1 == string2:325        return 0326    elif string1 < string2:327        return 1328    else:329        return -1330331con = sqlite3.connect(":memory:")332con.create_collation("reverse", collate_reverse)333334cur = con.cursor()335cur.execute("create table test(x)")336cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])337cur.execute("select x from test order by x collate reverse")338for row in cur:339    print(row)340con.close()341```342343Чтобы удалить сортировку, вызовите `create_collation` с параметром callable равным None:344345```python346con.create_collation("reverse", None)347```348349#### `interrupt()`350351Этот метод можно вызвать из другого потока, чтобы прервать любые запросы, которые могут выполняться в подключении. Запрос будет прерван, а вызывающий код получит исключение.352353#### `set_authorizer(authorizer_callback)`354355Эта процедура регистрирует колбэк. Колбэк вызывается при каждой попытке доступа к столбцу таблицы в базе данных. Колбэк должен возвращать `SQLITE_OK`, если доступ разрешён, `SQLITE_DENY`, если весь SQL-запрос должен быть прерван с ошибкой, и `SQLITE_IGNORE`, если столбец должен рассматриваться как значение NULL. Эти константы доступны в модуле [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3).356357Первый аргумент колбэка указывает, какой тип операции нужно авторизовать. Второй и третий аргументы будут аргументами или [`None`](https://python-all.ru/3.4/library/constants.html#None) в зависимости от первого аргумента. Четвёртый аргумент – это имя базы данных (например, «main», «temp»), если применимо. Пятый аргумент – это имя самого внутреннего триггера или представления, ответственного за попытку доступа, или [`None`](https://python-all.ru/3.4/library/constants.html#None), если эта попытка доступа происходит напрямую из входного SQL-кода.358359Обратитесь к документации SQLite для получения сведений о возможных значениях первого аргумента и значении второго и третьего аргументов в зависимости от первого. Все необходимые константы доступны в модуле [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3).360361#### `set_progress_handler(handler, n)`362363Эта процедура регистрирует колбэк. Колбэк вызывается каждые *n* инструкций виртуальной машины SQLite. Это полезно, если требуется получать вызовы от SQLite во время длительных операций, например для обновления графического интерфейса.364365Чтобы удалить ранее установленный обработчик хода выполнения, вызовите метод, передав [`None`](https://python-all.ru/3.4/library/constants.html#None) в качестве *handler*.366367#### `set_trace_callback(trace_callback)`368369Регистрирует *trace\_callback*, который будет вызываться для каждого SQL-выражения, фактически выполняемого серверной частью SQLite.370371Единственный аргумент, передаваемый колбэку – это выполняемый оператор (в виде строки). Возвращаемое значение колбэка игнорируется. Обратите внимание, что бэкенд выполняет не только операторы, переданные методам [`Cursor.execute()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute). Другие источники включают управление транзакциями модуля Python и выполнение триггеров, определённых в текущей базе данных.372373Передача [`None`](https://python-all.ru/3.4/library/constants.html#None) в качестве *trace\_callback* отключает трассировочный колбэк.374375Новое в версии 3.3.376377#### `enable_load_extension(enabled)`378379Эта процедура разрешает или запрещает механизму SQLite загружать расширения SQLite из разделяемых библиотек. Расширения SQLite могут определять новые функции, агрегатные функции или целые реализации виртуальных таблиц. Одним из известных расширений является расширение полнотекстового поиска, распространяемое с SQLite.380381Загружаемые расширения по умолчанию отключены. См. [\[1\]](https://python-all.ru/3.4/library/sqlite3.html#f1).382383Новое в версии 3.2.384385```python386import sqlite3387388con = sqlite3.connect(":memory:")389390# включить загрузку расширений391con.enable_load_extension(True)392393# Загрузить расширение полнотекстового поиска.394con.execute("select load_extension('./fts3.so')")395396# в качестве альтернативы можно загрузить расширение с помощью вызова API:397# con.load_extension("./fts3.so")398399# снова отключить загрузку расширения400con.enable_load_extension(False)401402# пример из вики SQLite403con.execute("create virtual table recipe using fts3(name, ingredients)")404con.executescript("""405    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');406    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');407    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');408    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');409    """)410for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):411    print(row)412```413414#### `load_extension(path)`415416Эта процедура загружает расширение SQLite из разделяемой библиотеки. Перед использованием этой процедуры необходимо включить загрузку расширений с помощью [`enable_load_extension()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.enable_load_extension).417418Загружаемые расширения по умолчанию отключены. См. [\[1\]](https://python-all.ru/3.4/library/sqlite3.html#f1).419420Новое в версии 3.2.421422#### `row_factory`423424Этот атрибут можно заменить на вызываемый объект, который принимает курсор и исходную строку в виде кортежа и возвращает реальную результирующую строку. Таким образом можно реализовать более продвинутые способы возврата результатов, например возврат объекта, который также может обращаться к столбцам по имени.425426Пример:427428```python429import sqlite3430431def dict_factory(cursor, row):432    d = {}433    for idx, col in enumerate(cursor.description):434        d[col[0]] = row[idx]435    return d436437con = sqlite3.connect(":memory:")438con.row_factory = dict_factory439cur = con.cursor()440cur.execute("select 1 as a")441print(cur.fetchone()["a"])442```443444Если возврата кортежа недостаточно и требуется доступ к столбцам по имени, рассмотрите возможность установки [`row_factory`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.row_factory) на высокооптимизированный тип [`sqlite3.Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row). [`Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row) предоставляет как доступ по индексу, так и регистронезависимый доступ по имени к столбцам с почти нулевыми накладными расходами памяти. Вероятно, это будет лучше, чем собственное решение на основе словаря или даже решения на основе db\_row.445446#### `text_factory`447448С помощью этого атрибута можно управлять тем, какие объекты возвращаются для типа данных `TEXT`. По умолчанию этот атрибут установлен в [`str`](https://python-all.ru/3.4/library/stdtypes.html#str), и модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) возвращает объекты Unicode для `TEXT`. Если вместо этого нужно возвращать байтовые строки, можно установить его в [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes).449450Из соображений эффективности существует также способ возвращать объекты [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) только для не-ASCII данных, а в остальных случаях – [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes). Чтобы активировать его, установите этот атрибут в `sqlite3.OptimizedUnicode`.451452Также можно установить его в любой другой вызываемый объект, принимающий единственный параметр – байтовую строку и возвращающий результирующий объект.453454См. следующий пример для иллюстрации:455456```python457import sqlite3458459con = sqlite3.connect(":memory:")460cur = con.cursor()461462AUSTRIA = "\xd6sterreich"463464# по умолчанию строки возвращаются как Unicode465cur.execute("select ?", (AUSTRIA,))466row = cur.fetchone()467assert row[0] == AUSTRIA468469# но можно заставить sqlite3 всегда возвращать байтовые строки...470con.text_factory = bytes471cur.execute("select ?", (AUSTRIA,))472row = cur.fetchone()473assert type(row[0]) is bytes474# байтовые строки будут в кодировке UTF-8, если только в базу не попал мусор475# база данных...476assert row[0] == AUSTRIA.encode("utf-8")477478# можно также реализовать собственный text_factory...479# здесь реализован такой, который добавляет "foo" ко всем строкам480con.text_factory = lambda x: x.decode("utf-8") + "foo"481cur.execute("select ?", ("bar",))482row = cur.fetchone()483assert row[0] == "barfoo"484```485486#### `total_changes`487488Возвращает общее количество строк базы данных, которые были изменены, вставлены или удалены с момента открытия подключения к базе данных.489490#### `iterdump`491492Возвращает итератор для дампа базы данных в формате SQL-текста. Полезно при сохранении базы данных в памяти для последующего восстановления. Эта функция предоставляет те же возможности, что и команда `.dump` в оболочке **sqlite3**.493494Пример:495496```python497# Преобразовать файл existing_db.db в SQL-дамп dump.sql498import sqlite3, os499500con = sqlite3.connect('existing_db.db')501with open('dump.sql', 'w') as f:502    for line in con.iterdump():503        f.write('%s\n' % line)504```505506## 12.6.3. Объекты курсора507508#### `class sqlite3.Cursor`509510Экземпляр [`Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor) имеет следующие атрибуты и методы.511512#### `execute(sql[, parameters])`513514Выполняет SQL-оператор. Оператор SQL может быть параметризованным (т.е. с плейсхолдерами вместо литералов SQL). Модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) поддерживает два вида плейсхолдеров: вопросительные знаки (стиль qmark) и именованные плейсхолдеры (именованный стиль).515516Вот пример обоих стилей:517518```python519import sqlite3520521con = sqlite3.connect(":memory:")522cur = con.cursor()523cur.execute("create table people (name_last, age)")524525who = "Yeltsin"526age = 72527528# Это стиль qmark:529cur.execute("insert into people values (?, ?)", (who, age))530531# А это именованный стиль:532cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})533534print(cur.fetchone())535```536537[`execute()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute) выполнит только один SQL-оператор. При попытке выполнить с его помощью более одного оператора будет выдано предупреждение. Используйте [`executescript()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.executescript), если требуется выполнить несколько операторов SQL одним вызовом.538539#### `executemany(sql, seq_of_parameters)`540541Выполняет SQL-команду для всех последовательностей параметров или отображений, найденных в последовательности *sql*. Модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) также позволяет использовать [*итератор*](https://python-all.ru/3.4/glossary.html#term-iterator), возвращающий параметры, вместо последовательности.542543```python544import sqlite3545546class IterChars:547    def __init__(self):548        self.count = ord('a')549550    def __iter__(self):551        return self552553    def __next__(self):554        if self.count > ord('z'):555            raise StopIteration556        self.count += 1557        return (chr(self.count - 1),) # это кортеж из одного элемента558559con = sqlite3.connect(":memory:")560cur = con.cursor()561cur.execute("create table characters(c)")562563theIter = IterChars()564cur.executemany("insert into characters(c) values (?)", theIter)565566cur.execute("select c from characters")567print(cur.fetchall())568```569570Вот более короткий пример с использованием [*генератора*](https://python-all.ru/3.4/glossary.html#term-generator):571572```python573import sqlite3574import string575576def char_generator():577    for c in string.ascii_lowercase:578        yield (c,)579580con = sqlite3.connect(":memory:")581cur = con.cursor()582cur.execute("create table characters(c)")583584cur.executemany("insert into characters(c) values (?)", char_generator())585586cur.execute("select c from characters")587print(cur.fetchall())588```589590#### `executescript(sql_script)`591592Это нестандартный удобный метод для выполнения нескольких SQL-операторов за один раз. Сначала он выдаёт оператор `COMMIT`, а затем выполняет SQL-скрипт, полученный в качестве параметра.593594*sql\_script* может быть экземпляром [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes).595596Пример:597598```python599import sqlite3600601con = sqlite3.connect(":memory:")602cur = con.cursor()603cur.executescript("""604    create table person(605        firstname,606        lastname,607        age608    );609610    create table book(611        title,612        author,613        published614    );615616    insert into book(title, author, published)617    values (618        'Dirk Gently''s Holistic Detective Agency',619        'Douglas Adams',620        1987621    );622    """)623```624625#### `fetchone()`626627Извлекает следующую строку результирующего набора запроса, возвращая одну последовательность или [`None`](https://python-all.ru/3.4/library/constants.html#None), когда данные закончились.628629#### `fetchmany(size=cursor.arraysize)`630631Извлекает следующий набор строк результата запроса, возвращая список. Пустой список возвращается, когда строк больше нет.632633Количество строк, извлекаемых за один вызов, задаётся параметром *size*. Если он не указан, количество строк определяется атрибутом arraysize курсора. Метод должен пытаться извлечь столько строк, сколько указано параметром size. Если это невозможно из-за того, что указанное количество строк недоступно, может быть возвращено меньше строк.634635Обратите внимание на вопросы производительности, связанные с параметром *size*. Для оптимальной производительности обычно лучше использовать атрибут arraysize. Если используется параметр *size*, то желательно, чтобы его значение оставалось неизменным от одного вызова [`fetchmany()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.fetchmany) к следующему.636637#### `fetchall()`638639Извлекает все (оставшиеся) строки результата запроса, возвращая список. Обратите внимание, что атрибут arraysize курсора может влиять на производительность этой операции. Пустой список возвращается, если строк нет.640641#### `rowcount`642643Хотя класс [`Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor) модуля [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) реализует этот атрибут, собственная поддержка определения «затронутых строк»/«выбранных строк» в движке базы данных отличается непредсказуемостью.644645Для инструкций [`executemany()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.executemany) количество изменений суммируется в [`rowcount`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.rowcount).646647Согласно требованиям спецификации Python DB API, атрибут [`rowcount`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.rowcount) «равен -1, если для курсора не выполнялся `executeXX()` или количество строк последней операции не может быть определено интерфейсом». Это включает инструкции `SELECT`, поскольку мы не можем определить количество строк, возвращаемых запросом, пока не будут получены все строки.648649В версиях SQLite до 3.6.5 атрибут [`rowcount`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.rowcount) устанавливается в 0, если выполнить `DELETE FROM table` без условия.650651#### `lastrowid`652653Этот атрибут только для чтения предоставляет rowid последней изменённой строки. Он устанавливается только при выполнении инструкции `INSERT` с помощью метода [`execute()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.execute). Для операций, отличных от `INSERT`, или при вызове [`executemany()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.executemany), [`lastrowid`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.lastrowid) устанавливается в [`None`](https://python-all.ru/3.4/library/constants.html#None).654655#### `description`656657Этот атрибут только для чтения возвращает имена столбцов последнего запроса. Для совместимости с Python DB API он возвращает для каждого столбца кортеж из 7 элементов, где последние шесть элементов каждого кортежа равны [`None`](https://python-all.ru/3.4/library/constants.html#None).658659Он также устанавливается для инструкций `SELECT`, даже если не найдено ни одной строки.660661## 12.6.4. Объекты строк662663#### `class sqlite3.Row`664665Экземпляр [`Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row) служит высокооптимизированной [`row_factory`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.row_factory) для объектов [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection). По большинству своих характеристик он имитирует кортеж.666667Он поддерживает доступ по имени столбца и индексу (как отображение), итерацию, представление, проверку на равенство и [`len()`](https://python-all.ru/3.4/library/functions.html#len).668669Если у двух объектов [`Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row) одинаковые столбцы и их элементы равны, то эти объекты считаются равными.670671#### `keys()`672673Этот метод возвращает список имён столбцов. Сразу после выполнения запроса это значение является первым элементом каждого кортежа в [`Cursor.description`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor.description).674675Предположим, мы инициализируем таблицу, как в приведённом выше примере:676677```python678conn = sqlite3.connect(":memory:")679c = conn.cursor()680c.execute('''create table stocks681(date text, trans text, symbol text,682 qty real, price real)''')683c.execute("""insert into stocks684          values ('2006-01-05','BUY','RHAT',100,35.14)""")685conn.commit()686c.close()687```688689Теперь подключаем [`Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row):690691```python692>>> conn.row_factory = sqlite3.Row693>>> c = conn.cursor()694>>> c.execute('select * from stocks')695<sqlite3.Cursor object at 0x7f4e7dd8fa80>696>>> r = c.fetchone()697>>> type(r)698<class 'sqlite3.Row'>699>>> tuple(r)700('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)701>>> len(r)7025703>>> r[2]704'RHAT'705>>> r.keys()706['date', 'trans', 'symbol', 'qty', 'price']707>>> r['qty']708100.0709>>> for member in r:710...     print(member)711...7122006-01-05713BUY714RHAT715100.071635.14717```718719## 12.6.5. SQLite и типы Python720721### 12.6.5.1. Введение722723SQLite изначально поддерживает следующие типы: `NULL`, `INTEGER`, `REAL`, `TEXT`, `BLOB`.724725Следующие типы Python можно передавать в SQLite без каких-либо проблем:726727| Тип Python | Тип SQLite |728| --- | --- |729| [`None`](https://python-all.ru/3.4/library/constants.html#None) | `NULL` |730| [`int`](https://python-all.ru/3.4/library/functions.html#int) | `INTEGER` |731| [`float`](https://python-all.ru/3.4/library/functions.html#float) | `REAL` |732| [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) | `TEXT` |733| [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) | `BLOB` |734735Так по умолчанию типы SQLite преобразуются в типы Python:736737| Тип SQLite | Тип Python |738| --- | --- |739| `NULL` | [`None`](https://python-all.ru/3.4/library/constants.html#None) |740| `INTEGER` | [`int`](https://python-all.ru/3.4/library/functions.html#int) |741| `REAL` | [`float`](https://python-all.ru/3.4/library/functions.html#float) |742| `TEXT` | зависит от [`text_factory`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.text_factory), [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) по умолчанию |743| `BLOB` | [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) |744745Система типов модуля [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) расширяема двумя способами: можно хранить дополнительные типы Python в базе данных SQLite с помощью адаптации объектов, и можно разрешить модулю [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) преобразовывать типы SQLite в другие типы Python с помощью конвертеров.746747### 12.6.5.2. Использование адаптеров для хранения дополнительных типов Python в базах данных SQLite748749Как описывалось ранее, SQLite изначально поддерживает только ограниченный набор типов. Чтобы использовать другие типы Python с SQLite, необходимо **адаптировать** их к одному из поддерживаемых модулем sqlite3 типов для SQLite: NoneType, int, float, str, bytes.750751Есть два способа дать модулю [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) возможность адаптировать пользовательский тип Python к одному из поддерживаемых.752753#### 12.6.5.2.1. Автоадаптация объекта754755Это хороший подход, если вы пишете класс сами. Предположим, у вас есть такой класс:756757```python758class Point:759    def __init__(self, x, y):760        self.x, self.y = x, y761```762763Теперь необходимо сохранить точку в одном столбце SQLite. Сначала нужно выбрать один из поддерживаемых типов для представления точки. Используем str и разделим координаты точкой с запятой. Затем классу нужно дать метод `__conform__(self, протокол)`, который должен возвращать преобразованное значение. Параметр *протокол* будет `PrepareProtocol`.764765```python766import sqlite3767768class Point:769    def __init__(self, x, y):770        self.x, self.y = x, y771772    def __conform__(self, protocol):773        if protocol is sqlite3.PrepareProtocol:774            return "%f;%f" % (self.x, self.y)775776con = sqlite3.connect(":memory:")777cur = con.cursor()778779p = Point(4.0, -3.2)780cur.execute("select ?", (p,))781print(cur.fetchone()[0])782```783784#### 12.6.5.2.2. Регистрация вызываемого адаптера785786Другая возможность – создать функцию, которая преобразует тип в строковое представление, и зарегистрировать её с помощью [`register_adapter()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.register_adapter).787788```python789import sqlite3790791class Point:792    def __init__(self, x, y):793        self.x, self.y = x, y794795def adapt_point(point):796    return "%f;%f" % (point.x, point.y)797798sqlite3.register_adapter(Point, adapt_point)799800con = sqlite3.connect(":memory:")801cur = con.cursor()802803p = Point(4.0, -3.2)804cur.execute("select ?", (p,))805print(cur.fetchone()[0])806```807808Модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) имеет два адаптера по умолчанию для встроенных типов Python [`datetime.date`](https://python-all.ru/3.4/library/datetime.html#datetime.date) и [`datetime.datetime`](https://python-all.ru/3.4/library/datetime.html#datetime.datetime). Теперь предположим, что мы хотим хранить объекты [`datetime.datetime`](https://python-all.ru/3.4/library/datetime.html#datetime.datetime) не в формате ISO, а в виде временной метки Unix.809810```python811import sqlite3812import datetime813import time814815def adapt_datetime(ts):816    return time.mktime(ts.timetuple())817818sqlite3.register_adapter(datetime.datetime, adapt_datetime)819820con = sqlite3.connect(":memory:")821cur = con.cursor()822823now = datetime.datetime.now()824cur.execute("select ?", (now,))825print(cur.fetchone()[0])826```827828### 12.6.5.3. Преобразование значений SQLite в пользовательские типы Python829830Написание адаптера позволяет отправлять пользовательские типы Python в SQLite. Но чтобы сделать это действительно полезным, нужно обеспечить обратное преобразование из SQLite в Python.831832Вступают конвертеры.833834Вернёмся к классу `Point`. Мы сохранили координаты x и y, разделённые точкой с запятой, в виде строк в SQLite.835836Сначала определим функцию-конвертер, которая принимает строку в качестве параметра и создаёт объект `Point` из неё.837838> **Примечание**839>840> Функции-конвертеры **всегда** вызываются с объектом [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), независимо от того, под каким типом данных значение было отправлено в SQLite.841842```python843def convert_point(s):844    x, y = map(float, s.split(b";"))845    return Point(x, y)846```847848Теперь необходимо сообщить модулю [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3), что выбираемое из базы данных на самом деле является точкой. Есть два способа сделать это:849850- Неявно, через объявленный тип851- Явно, по имени колонки852853Оба способа описаны в разделе [*Функции и константы модуля*](https://python-all.ru/3.4/library/sqlite3.html#sqlite3-module-contents), в записях для констант [`PARSE_DECLTYPES`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.PARSE_COLNAMES).854855Следующий пример иллюстрирует оба подхода.856857```python858import sqlite3859860class Point:861    def __init__(self, x, y):862        self.x, self.y = x, y863864    def __repr__(self):865        return "(%f;%f)" % (self.x, self.y)866867def adapt_point(point):868    return ("%f;%f" % (point.x, point.y)).encode('ascii')869870def convert_point(s):871    x, y = list(map(float, s.split(b";")))872    return Point(x, y)873874# Зарегистрировать адаптер875sqlite3.register_adapter(Point, adapt_point)876877# Зарегистрировать конвертер878sqlite3.register_converter("point", convert_point)879880p = Point(4.0, -3.2)881882#########################883# 1) Использование объявленных типов884con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)885cur = con.cursor()886cur.execute("create table test(p point)")887888cur.execute("insert into test(p) values (?)", (p,))889cur.execute("select p from test")890print("with declared types:", cur.fetchone()[0])891cur.close()892con.close()893894#######################895# 1) Использование имён столбцов896con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)897cur = con.cursor()898cur.execute("create table test(p)")899900cur.execute("insert into test(p) values (?)", (p,))901cur.execute('select p as "p [point]" from test')902print("with column names:", cur.fetchone()[0])903cur.close()904con.close()905```906907### 12.6.5.4. Адаптеры и конвертеры по умолчанию908909В модуле datetime есть адаптеры по умолчанию для типов date и datetime. Они отправляются в SQLite как даты/временные метки в формате ISO.910911Конвертеры по умолчанию зарегистрированы под именем “date” для [`datetime.date`](https://python-all.ru/3.4/library/datetime.html#datetime.date) и под именем “timestamp” для [`datetime.datetime`](https://python-all.ru/3.4/library/datetime.html#datetime.datetime).912913Таким образом, в большинстве случаев можно использовать даты и временные метки из Python без лишних усилий. Формат адаптеров также совместим с экспериментальными функциями даты/времени SQLite.914915Следующий пример демонстрирует это.916917```python918import sqlite3919import datetime920921con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)922cur = con.cursor()923cur.execute("create table test(d date, ts timestamp)")924925today = datetime.date.today()926now = datetime.datetime.now()927928cur.execute("insert into test(d, ts) values (?, ?)", (today, now))929cur.execute("select d, ts from test")930row = cur.fetchone()931print(today, "=>", row[0], type(row[0]))932print(now, "=>", row[1], type(row[1]))933934cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')935row = cur.fetchone()936print("current_date", row[0], type(row[0]))937print("current_timestamp", row[1], type(row[1]))938```939940Если временная метка, хранящаяся в SQLite, имеет дробную часть длиннее 6 знаков, её значение будет усечено до микросекундной точности преобразователем временных меток.941942## 12.6.6. Управление транзакциями943944По умолчанию модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) неявно открывает транзакции перед инструкциями языка модификации данных (DML) (т.е. `INSERT`/`UPDATE`/`DELETE`/`REPLACE`) и неявно фиксирует транзакции перед любой другой инструкцией (кроме `SELECT` и вышеупомянутых).945946Поэтому если вы находитесь внутри транзакции и выполняете команду наподобие `CREATE TABLE ...`, `VACUUM`, `PRAGMA`, модуль [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) перед выполнением этой команды неявно выполнит фиксацию. На то есть две причины. Первая – некоторые из этих команд не работают внутри транзакций. Другая причина в том, что sqlite3 необходимо отслеживать состояние транзакции (активна она или нет). Текущее состояние транзакции доступно через атрибут [`Connection.in_transaction`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.in_transaction) объекта соединения.947948Можно управлять тем, какие именно операторы `BEGIN` sqlite3 выполняет неявно (или не выполнять их вовсе) с помощью параметра *isolation\_level* вызова [`connect()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.connect), или с помощью свойства `isolation_level` соединений.949950Если нужен **режим автокоммита**, установите `isolation_level` в None.951952В противном случае оставьте его по умолчанию, что приведет к простой инструкции “BEGIN”, или установите одно из поддерживаемых уровней изоляции SQLite: “DEFERRED”, “IMMEDIATE” или “EXCLUSIVE”.953954## 12.6.7. Эффективное использование [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3)955956### 12.6.7.1. Использование сокращённых методов957958Используя нестандартные методы `execute()`, `executemany()` и `executescript()` объекта [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection), код можно написать более сжато, поскольку не нужно явно создавать (часто избыточные) объекты [`Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor). Вместо этого объекты [`Cursor`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Cursor) создаются неявно, и эти сокращённые методы возвращают объекты курсоров. Таким образом, можно выполнить оператор `SELECT` и итерироваться по нему напрямую, используя всего один вызов объекта [`Connection`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection).959960```python961import sqlite3962963persons = [964    ("Hugo", "Boss"),965    ("Calvin", "Klein")966    ]967968con = sqlite3.connect(":memory:")969970# Создать таблицу971con.execute("create table person(firstname, lastname)")972973# Заполнить таблицу974con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)975976# Выводит содержимое таблицы.977for row in con.execute("select firstname, lastname from person"):978    print(row)979980print("I just deleted", con.execute("delete from person").rowcount, "rows")981```982983### 12.6.7.2. Доступ к столбцам по имени, а не по индексу984985Одна из полезных возможностей модуля [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3) – встроенный класс [`sqlite3.Row`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Row), предназначенный для использования в качестве фабрики строк.986987Строки, обёрнутые этим классом, можно получать как по индексу (как кортежи), так и по имени без учёта регистра:988989```python990import sqlite3991992con = sqlite3.connect(":memory:")993con.row_factory = sqlite3.Row994995cur = con.cursor()996cur.execute("select 'John' as name, 42 as age")997for row in cur:998    assert row[0] == row["name"]999    assert row["name"] == row["nAmE"]1000    assert row[1] == row["age"]1001    assert row[1] == row["AgE"]1002```10031004### 12.6.7.3. Использование соединения как менеджера контекста10051006Объекты соединения можно использовать как менеджеры контекста, которые автоматически фиксируют или откатывают транзакции. В случае исключения транзакция откатывается; в противном случае транзакция фиксируется:10071008```python1009import sqlite310101011con = sqlite3.connect(":memory:")1012con.execute("create table person (id integer primary key, firstname varchar unique)")10131014# При успешном выполнении con.commit() вызывается автоматически.1015with con:1016    con.execute("insert into person(firstname) values (?)", ("Joe",))10171018# con.rollback() вызывается после завершения блока with с исключением,1019# исключение все равно возбуждается, и его необходимо перехватить1020try:1021    with con:1022        con.execute("insert into person(firstname) values (?)", ("Joe",))1023except sqlite3.IntegrityError:1024    print("couldn't add Joe twice")1025```10261027## 12.6.8. Типичные проблемы10281029### 12.6.8.1. Многопоточность10301031В старых версиях SQLite были проблемы с совместным использованием соединений между потоками. Именно поэтому модуль Python запрещает совместное использование соединений и курсоров между потоками. Если всё же попытаться это сделать, во время выполнения будет возбуждено исключение.10321033Единственное исключение – вызов метода [`interrupt()`](https://python-all.ru/3.4/library/sqlite3.html#sqlite3.Connection.interrupt), который имеет смысл вызывать только из другого потока.10341035Сноски10361037| \[1\] | *([1](https://python-all.ru/3.4/library/sqlite3.html#id1), [2](https://python-all.ru/3.4/library/sqlite3.html#id2))* Модуль sqlite3 по умолчанию не собирается с поддержкой загружаемых расширений, поскольку на некоторых платформах (в частности Mac OS X) библиотеки SQLite скомпилированы без этой возможности. Чтобы получить поддержку загружаемых расширений, необходимо передать параметр –enable-loadable-sqlite-extensions программе configure. |1038| --- | --- |1039