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

sqlite3.md

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

1> **Источник:** https://python-all.ru/3.3/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.3/library/sqlite3.html#module-sqlite3) – интерфейс DB-API 2.0 для баз данных SQLite89SQLite – это библиотека на C, которая предоставляет легковесную дисковую базу данных, не требующую отдельного серверного процесса, и позволяет обращаться к базе данных с помощью нестандартного варианта языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также можно создать прототип приложения на SQLite, а затем перенести код на более крупную базу данных, например PostgreSQL или Oracle.1011sqlite3 написан Герхардом Херингом и предоставляет SQL-интерфейс, соответствующий спецификации DB-API 2.0, описанной в [**PEP 249**](https://python-all.ru/3.3/library/sqlite3.html).1213Чтобы использовать модуль, сначала нужно создать объект [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection), представляющий базу данных. Здесь данные будут храниться в файле `example.db`:1415```python16import sqlite317conn = sqlite3.connect('example.db')18```1920Можно также указать специальное имя `:memory:`, чтобы создать базу данных в оперативной памяти.2122Когда у вас есть объект [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection), можно создать объект [`Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor) и вызывать его метод [`execute()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute) для выполнения SQL-команд:2324```python25c = conn.cursor()2627# Создать таблицу28c.execute('''create table stocks29(date text, trans text, symbol text,30 qty real, price real)''')3132# Вставить строку данных33c.execute("""insert into stocks34          values ('2006-01-05','BUY','RHAT',100,35.14)""")3536# Сохранить (зафиксировать) изменения37conn.commit()3839# Также можно закрыть курсор, если он больше не нужен.40c.close()41```4243Обычно вашим SQL-операциям потребуется использовать значения из переменных Python. Не следует собирать запрос с помощью строковых операций Python, потому что это небезопасно; это делает вашу программу уязвимой для SQL-инъекций.4445Вместо этого используйте подстановку параметров DB-API. Поставьте `?` в качестве заполнителя там, где нужно использовать значение, а затем передайте кортеж значений вторым аргументом методу [`execute()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute) курсора. (В других модулях баз данных может использоваться другой заполнитель, например `%s` или `:1`.) Например:4647```python48# Никогда не делайте этого – это небезопасно!49symbol = 'IBM'50c.execute("select * from stocks where symbol = '%s'" % symbol)5152# Вместо этого сделайте так53t = ('IBM',)54c.execute('select * from stocks where symbol=?', t)5556# Более крупный пример57for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),58          ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),59          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),60         ]:61    c.execute('insert into stocks values (?,?,?,?,?)', t)62```6364Чтобы извлечь данные после выполнения оператора SELECT, можно либо рассматривать курсор как [*итератор*](https://python-all.ru/3.3/glossary.html#term-iterator), вызывать его метод [`fetchone()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.fetchone) для получения одной подходящей строки, либо вызвать [`fetchall()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.fetchall) для получения списка всех подходящих строк.6566В этом примере используется форма итератора:6768```python69>>> c = conn.cursor()70>>> c.execute('select * from stocks order by price')71>>> for row in c:72...     print(row)73...74('2006-01-05', 'BUY', 'RHAT', 100, 35.14)75('2006-03-28', 'BUY', 'IBM', 1000, 45.0)76('2006-04-06', 'SELL', 'IBM', 500, 53.0)77('2006-04-05', 'BUY', 'MSOFT', 1000, 72.0)78>>>79```8081> **См. также**82>83> **[https://github.com/ghaering/pysqlite](https://python-all.ru/3.3/library/sqlite3.html)**84>85> Страница pysqlite – sqlite3 разрабатывается отдельно под названием «pysqlite».86>87> **[http://www.sqlite.org](https://python-all.ru/3.3/library/sqlite3.html)**88>89> Веб-страница SQLite; документация описывает синтаксис и доступные типы данных поддерживаемого диалекта SQL.90>91> **[**PEP 249**](https://python-all.ru/3.3/library/sqlite3.html) – спецификация API баз данных 2.0**92>93> PEP написан Марком-Андре Лембургом.9495## 12.6.1. Функции и константы модуля9697#### `sqlite3.version`9899Номер версии этого модуля в виде строки. Это не версия библиотеки SQLite.100101#### `sqlite3.version_info`102103Номер версии этого модуля в виде кортежа целых чисел. Это не версия библиотеки SQLite.104105#### `sqlite3.sqlite_version`106107Номер версии библиотеки SQLite времени выполнения в виде строки.108109#### `sqlite3.sqlite_version_info`110111Номер версии библиотеки SQLite времени выполнения в виде кортежа целых чисел.112113#### `sqlite3.PARSE_DECLTYPES`114115Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.connect).116117Если установить этот флаг, модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) будет анализировать объявленный тип для каждого возвращаемого столбца. Он извлечёт первое слово объявленного типа, например, для «integer primary key» извлечёт «integer», а для «number(10)» – «number». Затем для этого столбца будет выполнен поиск в словаре конвертеров и использована зарегистрированная для этого типа функция преобразования.118119#### `sqlite3.PARSE_COLNAMES`120121Эта константа предназначена для использования с параметром *detect\_types* функции [`connect()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.connect).122123Если установить этот флаг, интерфейс SQLite будет анализировать имя столбца для каждого возвращаемого столбца. Он будет искать строку вида \[mytype\] в имени столбца и затем считать, что «mytype» – это тип столбца. Далее будет выполнена попытка найти запись «mytype» в словаре конвертеров и используется найденная функция преобразования для возврата значения. Имя столбца, полученное из [`Cursor.description`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.description), – это только первое слово имени столбца; то есть если в SQL используется что-то вроде `'as "x [datetime]"'`, то будет извлечено всё до первого пробела: имя столбца будет просто «x».124125#### `sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements])`126127Открывает соединение с файлом базы данных SQLite *database*. Можно использовать `":memory:"`, чтобы открыть соединение с базой данных, расположенной в оперативной памяти, а не на диске.128129Когда к базе данных обращаются несколько соединений и один из процессов изменяет базу данных, база данных SQLite блокируется до завершения этой транзакции. Параметр *timeout* задаёт, как долго соединение должно ждать снятия блокировки, прежде чем возникнет исключение. Значение по умолчанию для параметра timeout – 5.0 (пять секунд).130131По поводу параметра *isolation\_level* обратитесь к свойству [`Connection.isolation_level`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.isolation_level) объектов [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection).132133SQLite изначально поддерживает только типы TEXT, INTEGER, REAL, BLOB и NULL. Если нужно использовать другие типы, потребуется добавить поддержку самостоятельно. Параметр *detect\_types* и использование собственных **конвертеров**, зарегистрированных с помощью функции уровня модуля [`register_converter()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.register_converter), позволяют легко это сделать.134135Параметр *detect\_types* по умолчанию равен 0 (т.е. выключен, определение типов отключено); его можно установить в любую комбинацию [`PARSE_DECLTYPES`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.PARSE_COLNAMES) для включения определения типов.136137По умолчанию модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) использует для вызова connect() свой класс [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection). Однако можно создать подкласс класса [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection) и заставить [`connect()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.connect) использовать ваш класс, передав его в параметре *factory*.138139Подробности см. в разделе [*Типы SQLite и Python*](https://python-all.ru/3.3/library/sqlite3.html#sqlite3-types) данного руководства.140141Модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) внутренне использует кеш операторов, чтобы избежать накладных расходов на разбор SQL. Если требуется явно задать количество операторов, кешируемых для соединения, можно установить параметр *cached\_statements*. Текущая реализация по умолчанию кеширует 100 операторов.142143#### `sqlite3.register_converter(typename, callable)`144145Регистрирует вызываемый объект для преобразования байтовой строки из базы данных в пользовательский тип Python. Этот вызываемый объект будет вызываться для всех значений базы данных, имеющих тип *typename*. О том, как работает определение типа, см. параметр *detect\_types* функции [`connect()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.connect). Обратите внимание, что регистр символов в *typename* и имени типа в запросе должны совпадать!146147#### `sqlite3.register_adapter(type, callable)`148149Регистрирует вызываемый объект для преобразования пользовательского типа Python *type* в один из поддерживаемых типов SQLite. Вызываемый объект *callable* принимает в качестве единственного параметра значение Python и должен возвращать значение одного из следующих типов: int, float, str или bytes.150151#### `sqlite3.complete_statement(sql)`152153Возвращает [`True`](https://python-all.ru/3.3/library/constants.html#True), если строка *sql* содержит одно или несколько полных SQL-выражений, завершённых точкой с запятой. При этом не проверяется синтаксическая корректность SQL – только отсутствие незакрытых строковых литералов и наличие точки с запятой в конце каждого выражения.154155Это можно использовать для создания оболочки для SQLite, как в следующем примере:156157```python158# Минимальная оболочка SQLite для экспериментов159160import sqlite3161162con = sqlite3.connect(":memory:")163con.isolation_level = None164cur = con.cursor()165166buffer = ""167168print("Enter your SQL commands to execute in sqlite3.")169print("Enter a blank line to exit.")170171while True:172    line = input()173    if line == "":174        break175    buffer += line176    if sqlite3.complete_statement(buffer):177        try:178            buffer = buffer.strip()179            cur.execute(buffer)180181            if buffer.lstrip().upper().startswith("SELECT"):182                print(cur.fetchall())183        except sqlite3.Error as e:184            print("An error occurred:", e.args[0])185        buffer = ""186187con.close()188```189190#### `sqlite3.enable_callback_tracebacks(flag)`191192По умолчанию трассировки не отображаются для пользовательских функций, агрегатов, преобразователей, колбэков авторизатора и т.д. Если нужно их отладить, можно вызвать эту функцию, установив *flag* в `True`. После этого трассировки от колбэков будут выводиться в `sys.stderr`. Чтобы снова отключить эту возможность, используйте [`False`](https://python-all.ru/3.3/library/constants.html#False).193194## 12.6.2. Объекты соединения195196#### `class sqlite3.Connection`197198Соединение с базой данных SQLite обладает следующими атрибутами и методами:199200#### `isolation_level`201202Получает или устанавливает текущий уровень изоляции. [`None`](https://python-all.ru/3.3/library/constants.html#None) для режима автокоммита или одно из значений «DEFERRED», «IMMEDIATE» или «EXCLUSIVE». Подробное объяснение приведено в разделе [*Управление транзакциями*](https://python-all.ru/3.3/library/sqlite3.html#sqlite3-controlling-transactions).203204#### `in_transaction`205206[`True`](https://python-all.ru/3.3/library/constants.html#True), если транзакция активна (есть незафиксированные изменения), и [`False`](https://python-all.ru/3.3/library/constants.html#False) в противном случае. Атрибут только для чтения.207208Новое в версии 3.2.209210#### `cursor([cursorClass])`211212Метод cursor принимает один необязательный параметр *cursorClass*. Если он указан, это должен быть пользовательский класс курсора, наследующий от [`sqlite3.Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor).213214#### `commit()`215216Этот метод фиксирует текущую транзакцию. Если его не вызвать, все изменения, сделанные после последнего вызова `commit()`, не будут видны из других подключений к базе данных. Если вы удивляетесь, почему не видите записанные данные, проверьте, не забыли ли вызвать этот метод.217218#### `rollback()`219220Этот метод откатывает все изменения в базе данных, сделанные после последнего вызова [`commit()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.commit).221222#### `close()`223224Этот метод закрывает подключение к базе данных. Обратите внимание, что он не вызывает автоматически [`commit()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.commit). Если просто закрыть подключение без предварительного вызова [`commit()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.commit), изменения будут потеряны!225226#### `execute(sql[, parameters])`227228Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`execute`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute) этого курсора с переданными параметрами.229230#### `executemany(sql[, parameters])`231232Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`executemany`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.executemany) этого курсора с переданными параметрами.233234#### `executescript(sql_script)`235236Это нестандартный сокращённый метод, который создаёт промежуточный объект курсора вызовом метода cursor, а затем вызывает метод [`executescript`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.executescript) этого курсора с переданными параметрами.237238#### `create_function(name, num_params, func)`239240Создаёт пользовательскую функцию, которую затем можно использовать в SQL-выражениях под именем *name*. *num\_params* – количество параметров, принимаемых функцией, а *func* – вызываемый объект Python, который будет вызываться как SQL-функция.241242Функция может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и None.243244Пример:245246```python247import sqlite3248import hashlib249250def md5sum(t):251    return hashlib.md5(t).hexdigest()252253con = sqlite3.connect(":memory:")254con.create_function("md5", 1, md5sum)255cur = con.cursor()256cur.execute("select md5(?)", (b"foo",))257print(cur.fetchone()[0])258```259260#### `create_aggregate(name, num_params, aggregate_class)`261262Создаёт пользовательскую агрегатную функцию.263264Класс агрегатной функции должен реализовывать метод `step`, который принимает количество параметров *num\_params*, и метод `finalize`, который возвращает конечный результат агрегации.265266Метод `finalize` может возвращать любой из типов, поддерживаемых SQLite: bytes, str, int, float и None.267268Пример:269270```python271import sqlite3272273class MySum:274    def __init__(self):275        self.count = 0276277    def step(self, value):278        self.count += value279280    def finalize(self):281        return self.count282283con = sqlite3.connect(":memory:")284con.create_aggregate("mysum", 1, MySum)285cur = con.cursor()286cur.execute("create table test(i)")287cur.execute("insert into test(i) values (1)")288cur.execute("insert into test(i) values (2)")289cur.execute("select mysum(i) from test")290print(cur.fetchone()[0])291```292293#### `create_collation(name, callable)`294295Создаёт collation с указанными *name* и *callable*. Вызываемый объект будет получать два строковых аргумента. Он должен возвращать -1, если первый меньше второго, 0, если они равны, и 1, если первый больше второго. Обратите внимание, что это управляет сортировкой (ORDER BY в SQL), поэтому сравнения не влияют на другие операции SQL.296297Обратите внимание, что вызываемый объект будет получать свои параметры в виде байтовых строк Python, которые обычно закодированы в UTF-8.298299Следующий пример показывает пользовательскую коллацию, которая сортирует «в обратном порядке»:300301```python302import sqlite3303304def collate_reverse(string1, string2):305    if string1 == string2:306        return 0307    elif string1 < string2:308        return 1309    else:310        return -1311312con = sqlite3.connect(":memory:")313con.create_collation("reverse", collate_reverse)314315cur = con.cursor()316cur.execute("create table test(x)")317cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])318cur.execute("select x from test order by x collate reverse")319for row in cur:320    print(row)321con.close()322```323324Чтобы удалить сортировку, вызовите `create_collation` с параметром callable равным None:325326```python327con.create_collation("reverse", None)328```329330#### `interrupt()`331332Этот метод можно вызвать из другого потока, чтобы прервать любые запросы, которые могут выполняться в подключении. Запрос будет прерван, а вызывающий код получит исключение.333334#### `set_authorizer(authorizer_callback)`335336Эта процедура регистрирует колбэк. Колбэк вызывается при каждой попытке доступа к столбцу таблицы в базе данных. Колбэк должен возвращать `SQLITE_OK`, если доступ разрешён, `SQLITE_DENY`, если весь SQL-запрос должен быть прерван с ошибкой, и `SQLITE_IGNORE`, если столбец должен рассматриваться как значение NULL. Эти константы доступны в модуле [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3).337338Первый аргумент колбэка указывает, какой тип операции нужно авторизовать. Второй и третий аргументы будут аргументами или [`None`](https://python-all.ru/3.3/library/constants.html#None) в зависимости от первого аргумента. Четвёртый аргумент – это имя базы данных (например, «main», «temp»), если применимо. Пятый аргумент – это имя самого внутреннего триггера или представления, ответственного за попытку доступа, или [`None`](https://python-all.ru/3.3/library/constants.html#None), если эта попытка доступа происходит напрямую из входного SQL-кода.339340Обратитесь к документации SQLite для получения сведений о возможных значениях первого аргумента и значении второго и третьего аргументов в зависимости от первого. Все необходимые константы доступны в модуле [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3).341342#### `set_progress_handler(handler, n)`343344Эта процедура регистрирует колбэк. Колбэк вызывается каждые *n* инструкций виртуальной машины SQLite. Это полезно, если требуется получать вызовы от SQLite во время длительных операций, например для обновления графического интерфейса.345346Чтобы удалить ранее установленный обработчик хода выполнения, вызовите метод, передав [`None`](https://python-all.ru/3.3/library/constants.html#None) в качестве *handler*.347348#### `set_trace_callback(trace_callback)`349350Регистрирует *trace\_callback*, который будет вызываться для каждого SQL-выражения, фактически выполняемого серверной частью SQLite.351352Единственный аргумент, передаваемый колбэку – это выполняемый оператор (в виде строки). Возвращаемое значение колбэка игнорируется. Обратите внимание, что бэкенд выполняет не только операторы, переданные методам [`Cursor.execute()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute). Другие источники включают управление транзакциями модуля Python и выполнение триггеров, определённых в текущей базе данных.353354Передача [`None`](https://python-all.ru/3.3/library/constants.html#None) в качестве *trace\_callback* отключает трассировочный колбэк.355356Новое в версии 3.3.357358#### `enable_load_extension(enabled)`359360Эта процедура разрешает или запрещает механизму SQLite загружать расширения SQLite из разделяемых библиотек. Расширения SQLite могут определять новые функции, агрегатные функции или целые реализации виртуальных таблиц. Одним из известных расширений является расширение полнотекстового поиска, распространяемое с SQLite.361362Загружаемые расширения по умолчанию отключены. См. [\[1\]](https://python-all.ru/3.3/library/sqlite3.html#f1).363364Новое в версии 3.2.365366```python367import sqlite3368369con = sqlite3.connect(":memory:")370371# включить загрузку расширений372con.enable_load_extension(True)373374# Загрузить расширение полнотекстового поиска.375con.execute("select load_extension('./fts3.so')")376377# в качестве альтернативы можно загрузить расширение с помощью вызова API:378# con.load_extension("./fts3.so")379380# снова отключить загрузку расширения381con.enable_load_extension(False)382383# пример из вики SQLite384con.execute("create virtual table recipe using fts3(name, ingredients)")385con.executescript("""386    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');387    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');388    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');389    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');390    """)391for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):392    print(row)393```394395#### `load_extension(path)`396397Эта процедура загружает расширение SQLite из разделяемой библиотеки. Перед использованием этой процедуры необходимо включить загрузку расширений с помощью [`enable_load_extension()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.enable_load_extension).398399Загружаемые расширения по умолчанию отключены. См. [\[1\]](https://python-all.ru/3.3/library/sqlite3.html#f1).400401Новое в версии 3.2.402403#### `row_factory`404405Этот атрибут можно заменить на вызываемый объект, который принимает курсор и исходную строку в виде кортежа и возвращает реальную результирующую строку. Таким образом можно реализовать более продвинутые способы возврата результатов, например возврат объекта, который также может обращаться к столбцам по имени.406407Пример:408409```python410import sqlite3411412def dict_factory(cursor, row):413    d = {}414    for idx, col in enumerate(cursor.description):415        d[col[0]] = row[idx]416    return d417418con = sqlite3.connect(":memory:")419con.row_factory = dict_factory420cur = con.cursor()421cur.execute("select 1 as a")422print(cur.fetchone()["a"])423```424425Если возврата кортежа недостаточно и требуется доступ к столбцам по имени, рассмотрите возможность установки [`row_factory`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.row_factory) на высокооптимизированный тип [`sqlite3.Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row). [`Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row) предоставляет как доступ по индексу, так и регистронезависимый доступ по имени к столбцам с почти нулевыми накладными расходами памяти. Вероятно, это будет лучше, чем собственное решение на основе словаря или даже решения на основе db\_row.426427#### `text_factory`428429С помощью этого атрибута можно управлять тем, какие объекты возвращаются для типа данных `TEXT`. По умолчанию этот атрибут установлен в [`str`](https://python-all.ru/3.3/library/stdtypes.html#str), и модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) возвращает объекты Unicode для `TEXT`. Если вместо этого нужно возвращать байтовые строки, можно установить его в [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes).430431Из соображений эффективности существует также способ возвращать объекты [`str`](https://python-all.ru/3.3/library/stdtypes.html#str) только для не-ASCII данных, а в остальных случаях – [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes). Чтобы активировать его, установите этот атрибут в `sqlite3.OptimizedUnicode`.432433Также можно установить его в любой другой вызываемый объект, принимающий единственный параметр – байтовую строку и возвращающий результирующий объект.434435См. следующий пример для иллюстрации:436437```python438import sqlite3439440con = sqlite3.connect(":memory:")441cur = con.cursor()442443AUSTRIA = "\xd6sterreich"444445# по умолчанию строки возвращаются как Unicode446cur.execute("select ?", (AUSTRIA,))447row = cur.fetchone()448assert row[0] == AUSTRIA449450# но можно заставить sqlite3 всегда возвращать байтовые строки...451con.text_factory = bytes452cur.execute("select ?", (AUSTRIA,))453row = cur.fetchone()454assert type(row[0]) is bytes455# байтовые строки будут в кодировке UTF-8, если только в базу не попал мусор456# база данных...457assert row[0] == AUSTRIA.encode("utf-8")458459# можно также реализовать собственный text_factory...460# здесь реализован такой, который добавляет "foo" ко всем строкам461con.text_factory = lambda x: x.decode("utf-8") + "foo"462cur.execute("select ?", ("bar",))463row = cur.fetchone()464assert row[0] == "barfoo"465```466467#### `total_changes`468469Возвращает общее количество строк базы данных, которые были изменены, вставлены или удалены с момента открытия подключения к базе данных.470471#### `iterdump`472473Возвращает итератор для дампа базы данных в формате SQL-текста. Полезно при сохранении базы данных в памяти для последующего восстановления. Эта функция предоставляет те же возможности, что и команда `.dump` в оболочке **sqlite3**.474475Пример:476477```python478# Преобразовать файл existing_db.db в SQL-дамп dump.sql479import sqlite3, os480481con = sqlite3.connect('existing_db.db')482with open('dump.sql', 'w') as f:483    for line in con.iterdump():484        f.write('%s\n' % line)485```486487## 12.6.3. Объекты курсора488489#### `class sqlite3.Cursor`490491Экземпляр [`Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor) имеет следующие атрибуты и методы.492493#### `execute(sql[, parameters])`494495Выполняет SQL-запрос. Запрос может быть параметризован (т. е. можно использовать плейсхолдеры вместо литералов SQL). Модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) поддерживает два вида плейсхолдеров: вопросительные знаки (стиль qmark) и именованные плейсхолдеры (именованный стиль).496497Вот пример обоих стилей:498499```python500import sqlite3501502con = sqlite3.connect(":memory:")503cur = con.cursor()504cur.execute("create table people (name_last, age)")505506who = "Yeltsin"507age = 72508509# Это стиль qmark:510cur.execute("insert into people values (?, ?)", (who, age))511512# А это именованный стиль:513cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})514515print(cur.fetchone())516```517518[`execute()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute) выполнит только один SQL-оператор. При попытке выполнить с его помощью более одного оператора будет выдано предупреждение. Используйте [`executescript()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.executescript), если требуется выполнить несколько операторов SQL одним вызовом.519520#### `executemany(sql, seq_of_parameters)`521522Выполняет SQL-команду для всех последовательностей параметров или отображений, найденных в последовательности *sql*. Модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) также позволяет использовать [*итератор*](https://python-all.ru/3.3/glossary.html#term-iterator), возвращающий параметры, вместо последовательности.523524```python525import sqlite3526527class IterChars:528    def __init__(self):529        self.count = ord('a')530531    def __iter__(self):532        return self533534    def __next__(self):535        if self.count > ord('z'):536            raise StopIteration537        self.count += 1538        return (chr(self.count - 1),) # это кортеж из одного элемента539540con = sqlite3.connect(":memory:")541cur = con.cursor()542cur.execute("create table characters(c)")543544theIter = IterChars()545cur.executemany("insert into characters(c) values (?)", theIter)546547cur.execute("select c from characters")548print(cur.fetchall())549```550551Вот более короткий пример с использованием [*генератора*](https://python-all.ru/3.3/glossary.html#term-generator):552553```python554import sqlite3555import string556557def char_generator():558    for c in string.ascii_lowercase:559        yield (c,)560561con = sqlite3.connect(":memory:")562cur = con.cursor()563cur.execute("create table characters(c)")564565cur.executemany("insert into characters(c) values (?)", char_generator())566567cur.execute("select c from characters")568print(cur.fetchall())569```570571#### `executescript(sql_script)`572573Это нестандартный удобный метод для выполнения нескольких SQL-операторов за один раз. Сначала он выдаёт оператор `COMMIT`, а затем выполняет SQL-скрипт, полученный в качестве параметра.574575*sql\_script* может быть экземпляром [`str`](https://python-all.ru/3.3/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes).576577Пример:578579```python580import sqlite3581582con = sqlite3.connect(":memory:")583cur = con.cursor()584cur.executescript("""585    create table person(586        firstname,587        lastname,588        age589    );590591    create table book(592        title,593        author,594        published595    );596597    insert into book(title, author, published)598    values (599        'Dirk Gently''s Holistic Detective Agency',600        'Douglas Adams',601        1987602    );603    """)604```605606#### `fetchone()`607608Извлекает следующую строку результирующего набора запроса, возвращая одну последовательность или [`None`](https://python-all.ru/3.3/library/constants.html#None), когда данные закончились.609610#### `fetchmany(size=cursor.arraysize)`611612Извлекает следующий набор строк результата запроса, возвращая список. Пустой список возвращается, когда строк больше нет.613614Количество строк, извлекаемых за один вызов, задаётся параметром *size*. Если он не указан, количество строк определяется атрибутом arraysize курсора. Метод должен пытаться извлечь столько строк, сколько указано параметром size. Если это невозможно из-за того, что указанное количество строк недоступно, может быть возвращено меньше строк.615616Обратите внимание на вопросы производительности, связанные с параметром *size*. Для оптимальной производительности обычно лучше использовать атрибут arraysize. Если используется параметр *size*, то желательно, чтобы его значение оставалось неизменным от одного вызова [`fetchmany()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.fetchmany) к следующему.617618#### `fetchall()`619620Извлекает все (оставшиеся) строки результата запроса, возвращая список. Обратите внимание, что атрибут arraysize курсора может влиять на производительность этой операции. Пустой список возвращается, если строк нет.621622#### `rowcount`623624Хотя класс [`Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor) модуля [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) реализует этот атрибут, собственная поддержка определения «затронутых строк»/«выбранных строк» в движке базы данных отличается непредсказуемостью.625626Для инструкций [`executemany()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.executemany) количество изменений суммируется в [`rowcount`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.rowcount).627628Согласно требованиям спецификации Python DB API, атрибут [`rowcount`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.rowcount) «равен -1, если для курсора не выполнялся `executeXX()` или количество строк последней операции не может быть определено интерфейсом». Это включает инструкции `SELECT`, поскольку мы не можем определить количество строк, возвращаемых запросом, пока не будут получены все строки.629630В версиях SQLite до 3.6.5 атрибут [`rowcount`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.rowcount) устанавливается в 0, если выполнить `DELETE FROM table` без условия.631632#### `lastrowid`633634Этот доступный только для чтения атрибут возвращает rowid последней изменённой строки. Он устанавливается только в том случае, если с помощью метода [`execute()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.execute) был выполнен оператор `INSERT`. Для операций, отличных от `INSERT`, или при вызове [`executemany()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.executemany), значение [`lastrowid`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.lastrowid) устанавливается равным [`None`](https://python-all.ru/3.3/library/constants.html#None).635636#### `description`637638Этот атрибут только для чтения возвращает имена столбцов последнего запроса. Для совместимости с Python DB API он возвращает для каждого столбца кортеж из 7 элементов, где последние шесть элементов каждого кортежа равны [`None`](https://python-all.ru/3.3/library/constants.html#None).639640Он также устанавливается для инструкций `SELECT`, даже если не найдено ни одной строки.641642## 12.6.4. Объекты строк643644#### `class sqlite3.Row`645646Экземпляр [`Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row) служит высокооптимизированной [`row_factory`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.row_factory) для объектов [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection). По большинству своих характеристик он имитирует кортеж.647648Он поддерживает доступ по имени столбца и индексу (как отображение), итерацию, представление, проверку на равенство и [`len()`](https://python-all.ru/3.3/library/functions.html#len).649650Если у двух объектов [`Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row) одинаковые столбцы и их элементы равны, то эти объекты считаются равными.651652#### `keys()`653654Этот метод возвращает кортеж имён столбцов. Сразу после выполнения запроса он становится первым элементом каждого кортежа в [`Cursor.description`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor.description).655656Предположим, мы инициализируем таблицу, как в приведённом выше примере:657658```python659conn = sqlite3.connect(":memory:")660c = conn.cursor()661c.execute('''create table stocks662(date text, trans text, symbol text,663 qty real, price real)''')664c.execute("""insert into stocks665          values ('2006-01-05','BUY','RHAT',100,35.14)""")666conn.commit()667c.close()668```669670Теперь подключаем [`Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row):671672```python673>>> conn.row_factory = sqlite3.Row674>>> c = conn.cursor()675>>> c.execute('select * from stocks')676<sqlite3.Cursor object at 0x7f4e7dd8fa80>677>>> r = c.fetchone()678>>> type(r)679<class 'sqlite3.Row'>680>>> tuple(r)681('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)682>>> len(r)6835684>>> r[2]685'RHAT'686>>> r.keys()687['date', 'trans', 'symbol', 'qty', 'price']688>>> r['qty']689100.0690>>> for member in r:691...     print(member)692...6932006-01-05694BUY695RHAT696100.069735.14698```699700## 12.6.5. SQLite и типы Python701702### 12.6.5.1. Введение703704SQLite изначально поддерживает следующие типы: `NULL`, `INTEGER`, `REAL`, `TEXT`, `BLOB`.705706Следующие типы Python можно передавать в SQLite без каких-либо проблем:707708| Тип Python | Тип SQLite |709| --- | --- |710| [`None`](https://python-all.ru/3.3/library/constants.html#None) | `NULL` |711| [`int`](https://python-all.ru/3.3/library/functions.html#int) | `INTEGER` |712| [`float`](https://python-all.ru/3.3/library/functions.html#float) | `REAL` |713| [`str`](https://python-all.ru/3.3/library/stdtypes.html#str) | `TEXT` |714| [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes) | `BLOB` |715716Так по умолчанию типы SQLite преобразуются в типы Python:717718| Тип SQLite | Тип Python |719| --- | --- |720| `NULL` | [`None`](https://python-all.ru/3.3/library/constants.html#None) |721| `INTEGER` | [`int`](https://python-all.ru/3.3/library/functions.html#int) |722| `REAL` | [`float`](https://python-all.ru/3.3/library/functions.html#float) |723| `TEXT` | зависит от text\_factory, по умолчанию str |724| `BLOB` | [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes) |725726Система типов модуля [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) расширяема двумя способами: можно хранить дополнительные типы Python в базе данных SQLite с помощью адаптации объектов, и можно разрешить модулю [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) преобразовывать типы SQLite в другие типы Python с помощью конвертеров.727728### 12.6.5.2. Использование адаптеров для хранения дополнительных типов Python в базах данных SQLite729730Как описывалось ранее, SQLite изначально поддерживает только ограниченный набор типов. Чтобы использовать другие типы Python с SQLite, необходимо **адаптировать** их к одному из поддерживаемых модулем sqlite3 типов для SQLite: NoneType, int, float, str, bytes.731732Модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) использует адаптацию объектов Python, как описано в [**PEP 246**](https://python-all.ru/3.3/library/sqlite3.html) для этого. Протокол, который следует использовать, – `PrepareProtocol`.733734Есть два способа дать модулю [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) возможность адаптировать пользовательский тип Python к одному из поддерживаемых.735736#### 12.6.5.2.1. Автоадаптация объекта737738Это хороший подход, если вы пишете класс сами. Предположим, у вас есть такой класс:739740```python741class Point:742    def __init__(self, x, y):743        self.x, self.y = x, y744```745746Теперь необходимо сохранить точку в одном столбце SQLite. Сначала нужно выбрать один из поддерживаемых типов для представления точки. Используем str и разделим координаты точкой с запятой. Затем классу нужно дать метод `__conform__(self, протокол)`, который должен возвращать преобразованное значение. Параметр *протокол* будет `PrepareProtocol`.747748```python749import sqlite3750751class Point:752    def __init__(self, x, y):753        self.x, self.y = x, y754755    def __conform__(self, protocol):756        if protocol is sqlite3.PrepareProtocol:757            return "%f;%f" % (self.x, self.y)758759con = sqlite3.connect(":memory:")760cur = con.cursor()761762p = Point(4.0, -3.2)763cur.execute("select ?", (p,))764print(cur.fetchone()[0])765```766767#### 12.6.5.2.2. Регистрация вызываемого адаптера768769Другая возможность – создать функцию, которая преобразует тип в строковое представление, и зарегистрировать её с помощью [`register_adapter()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.register_adapter).770771```python772import sqlite3773774class Point:775    def __init__(self, x, y):776        self.x, self.y = x, y777778def adapt_point(point):779    return "%f;%f" % (point.x, point.y)780781sqlite3.register_adapter(Point, adapt_point)782783con = sqlite3.connect(":memory:")784cur = con.cursor()785786p = Point(4.0, -3.2)787cur.execute("select ?", (p,))788print(cur.fetchone()[0])789```790791Модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) имеет два адаптера по умолчанию для встроенных типов Python [`datetime.date`](https://python-all.ru/3.3/library/datetime.html#datetime.date) и [`datetime.datetime`](https://python-all.ru/3.3/library/datetime.html#datetime.datetime). Теперь предположим, что мы хотим хранить объекты [`datetime.datetime`](https://python-all.ru/3.3/library/datetime.html#datetime.datetime) не в формате ISO, а в виде временной метки Unix.792793```python794import sqlite3795import datetime796import time797798def adapt_datetime(ts):799    return time.mktime(ts.timetuple())800801sqlite3.register_adapter(datetime.datetime, adapt_datetime)802803con = sqlite3.connect(":memory:")804cur = con.cursor()805806now = datetime.datetime.now()807cur.execute("select ?", (now,))808print(cur.fetchone()[0])809```810811### 12.6.5.3. Преобразование значений SQLite в пользовательские типы Python812813Написание адаптера позволяет отправлять пользовательские типы Python в SQLite. Но чтобы сделать это действительно полезным, нужно обеспечить обратное преобразование из SQLite в Python.814815Вступают конвертеры.816817Вернёмся к классу `Point`. Мы сохранили координаты x и y, разделённые точкой с запятой, в виде строк в SQLite.818819Сначала определим функцию-конвертер, которая принимает строку в качестве параметра и создаёт объект `Point` из неё.820821> **Примечание**822>823> Функции преобразования **всегда** вызываются со строкой, независимо от того, под каким tипом данных значение было отправлено в SQLite.824825```python826def convert_point(s):827    x, y = map(float, s.split(b";"))828    return Point(x, y)829```830831Теперь необходимо сообщить модулю [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3), что выбираемое из базы данных на самом деле является точкой. Есть два способа сделать это:832833- Неявно, через объявленный тип834- Явно, по имени колонки835836Оба способа описаны в разделе [*Функции и константы модуля*](https://python-all.ru/3.3/library/sqlite3.html#sqlite3-module-contents), в записях для констант [`PARSE_DECLTYPES`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.PARSE_DECLTYPES) и [`PARSE_COLNAMES`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.PARSE_COLNAMES).837838Следующий пример иллюстрирует оба подхода.839840```python841import sqlite3842843class Point:844    def __init__(self, x, y):845        self.x, self.y = x, y846847    def __repr__(self):848        return "(%f;%f)" % (self.x, self.y)849850def adapt_point(point):851    return ("%f;%f" % (point.x, point.y)).encode('ascii')852853def convert_point(s):854    x, y = list(map(float, s.split(b";")))855    return Point(x, y)856857# Зарегистрировать адаптер858sqlite3.register_adapter(Point, adapt_point)859860# Зарегистрировать конвертер861sqlite3.register_converter("point", convert_point)862863p = Point(4.0, -3.2)864865#########################866# 1) Использование объявленных типов867con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)868cur = con.cursor()869cur.execute("create table test(p point)")870871cur.execute("insert into test(p) values (?)", (p,))872cur.execute("select p from test")873print("with declared types:", cur.fetchone()[0])874cur.close()875con.close()876877#######################878# 1) Использование имён столбцов879con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)880cur = con.cursor()881cur.execute("create table test(p)")882883cur.execute("insert into test(p) values (?)", (p,))884cur.execute('select p as "p [point]" from test')885print("with column names:", cur.fetchone()[0])886cur.close()887con.close()888```889890### 12.6.5.4. Адаптеры и конвертеры по умолчанию891892В модуле datetime есть адаптеры по умолчанию для типов date и datetime. Они отправляются в SQLite как даты/временные метки в формате ISO.893894Конвертеры по умолчанию зарегистрированы под именем “date” для [`datetime.date`](https://python-all.ru/3.3/library/datetime.html#datetime.date) и под именем “timestamp” для [`datetime.datetime`](https://python-all.ru/3.3/library/datetime.html#datetime.datetime).895896Таким образом, в большинстве случаев можно использовать даты и временные метки из Python без лишних усилий. Формат адаптеров также совместим с экспериментальными функциями даты/времени SQLite.897898Следующий пример демонстрирует это.899900```python901import sqlite3902import datetime903904con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)905cur = con.cursor()906cur.execute("create table test(d date, ts timestamp)")907908today = datetime.date.today()909now = datetime.datetime.now()910911cur.execute("insert into test(d, ts) values (?, ?)", (today, now))912cur.execute("select d, ts from test")913row = cur.fetchone()914print(today, "=>", row[0], type(row[0]))915print(now, "=>", row[1], type(row[1]))916917cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')918row = cur.fetchone()919print("current_date", row[0], type(row[0]))920print("current_timestamp", row[1], type(row[1]))921```922923Если временная метка, хранящаяся в SQLite, имеет дробную часть длиннее 6 знаков, её значение будет усечено до микросекундной точности преобразователем временных меток.924925## 12.6.6. Управление транзакциями926927По умолчанию модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) неявно открывает транзакции перед инструкциями языка модификации данных (DML) (т.е. `INSERT`/`UPDATE`/`DELETE`/`REPLACE`) и неявно фиксирует транзакции перед любой другой инструкцией (кроме `SELECT` и вышеупомянутых).928929Поэтому если вы находитесь внутри транзакции и выполняете команду наподобие `CREATE TABLE ...`, `VACUUM`, `PRAGMA`, модуль [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) перед выполнением этой команды неявно выполнит фиксацию. На то есть две причины. Первая – некоторые из этих команд не работают внутри транзакций. Другая причина в том, что sqlite3 необходимо отслеживать состояние транзакции (активна она или нет). Текущее состояние транзакции доступно через атрибут [`Connection.in_transaction`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.in_transaction) объекта соединения.930931Можно управлять тем, какие именно операторы `BEGIN` sqlite3 выполняет неявно (или не выполнять их вовсе) с помощью параметра *isolation\_level* вызова [`connect()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.connect), или с помощью свойства `isolation_level` соединений.932933Если нужен **режим автокоммита**, установите `isolation_level` в None.934935В противном случае оставьте его по умолчанию, что приведет к простой инструкции “BEGIN”, или установите одно из поддерживаемых уровней изоляции SQLite: “DEFERRED”, “IMMEDIATE” или “EXCLUSIVE”.936937## 12.6.7. Эффективное использование [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3)938939### 12.6.7.1. Использование сокращённых методов940941Используя нестандартные методы `execute()`, `executemany()` и `executescript()` объекта [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection), код можно написать более сжато, поскольку не нужно явно создавать (часто избыточные) объекты [`Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor). Вместо этого объекты [`Cursor`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Cursor) создаются неявно, и эти сокращённые методы возвращают объекты курсоров. Таким образом, можно выполнить оператор `SELECT` и итерироваться по нему напрямую, используя всего один вызов объекта [`Connection`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection).942943```python944import sqlite3945946persons = [947    ("Hugo", "Boss"),948    ("Calvin", "Klein")949    ]950951con = sqlite3.connect(":memory:")952953# Создать таблицу954con.execute("create table person(firstname, lastname)")955956# Заполнить таблицу957con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)958959# Выводит содержимое таблицы.960for row in con.execute("select firstname, lastname from person"):961    print(row)962963print("I just deleted", con.execute("delete from person").rowcount, "rows")964```965966### 12.6.7.2. Доступ к столбцам по имени, а не по индексу967968Одна из полезных возможностей модуля [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3) – встроенный класс [`sqlite3.Row`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Row), предназначенный для использования в качестве фабрики строк.969970Строки, обёрнутые этим классом, можно получать как по индексу (как кортежи), так и по имени без учёта регистра:971972```python973import sqlite3974975con = sqlite3.connect(":memory:")976con.row_factory = sqlite3.Row977978cur = con.cursor()979cur.execute("select 'John' as name, 42 as age")980for row in cur:981    assert row[0] == row["name"]982    assert row["name"] == row["nAmE"]983    assert row[1] == row["age"]984    assert row[1] == row["AgE"]985```986987### 12.6.7.3. Использование соединения как менеджера контекста988989Объекты соединения можно использовать как менеджеры контекста, которые автоматически фиксируют или откатывают транзакции. В случае исключения транзакция откатывается; в противном случае транзакция фиксируется:990991```python992import sqlite3993994con = sqlite3.connect(":memory:")995con.execute("create table person (id integer primary key, firstname varchar unique)")996997# При успешном выполнении con.commit() вызывается автоматически.998with con:999    con.execute("insert into person(firstname) values (?)", ("Joe",))10001001# con.rollback() вызывается после завершения блока with с исключением,1002# исключение все равно возбуждается, и его необходимо перехватить1003try:1004    with con:1005        con.execute("insert into person(firstname) values (?)", ("Joe",))1006except sqlite3.IntegrityError:1007    print("couldn't add Joe twice")1008```10091010## 12.6.8. Типичные проблемы10111012### 12.6.8.1. Многопоточность10131014В старых версиях SQLite были проблемы с совместным использованием соединений между потоками. Именно поэтому модуль Python запрещает совместное использование соединений и курсоров между потоками. Если всё же попытаться это сделать, во время выполнения будет возбуждено исключение.10151016Единственное исключение – вызов метода [`interrupt()`](https://python-all.ru/3.3/library/sqlite3.html#sqlite3.Connection.interrupt), который имеет смысл вызывать только из другого потока.10171018Сноски10191020| \[1\] | *([1](https://python-all.ru/3.3/library/sqlite3.html#id1), [2](https://python-all.ru/3.3/library/sqlite3.html#id2))* Модуль sqlite3 по умолчанию не собирается с поддержкой загружаемых расширений, поскольку на некоторых платформах (в частности Mac OS X) библиотеки SQLite скомпилированы без этой возможности. Чтобы получить поддержку загружаемых расширений, необходимо передать параметр –enable-loadable-sqlite-extensions программе configure. |1021| --- | --- |1022