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

11.13. sqlite3 – интерфейс DB-API 2.0 для баз данных SQLitesqlite3 – DB-API 2.0 interface for SQLite databases

Новое в версии 2.5.

SQLite – это библиотека на C, которая предоставляет легковесную дисковую базу данных, не требующую отдельного серверного процесса, и позволяет обращаться к базе данных с помощью нестандартного варианта языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также можно создать прототип приложения на SQLite, а затем перенести код на более крупную базу данных, например PostgreSQL или Oracle.

Модуль sqlite3 написан Герхардом Харингом. Он предоставляет SQL-интерфейс, соответствующий спецификации DB-API 2.0, описанной в PEP 249.

Чтобы использовать модуль, сначала необходимо создать объект Connection, который представляет базу данных. Здесь данные будут храниться в файле example.db:

import sqlite3
conn = sqlite3.connect('example.db')

Также можно указать специальное имя :memory: для создания базы данных в оперативной памяти.

После получения Connection можно создать объект Cursor и вызвать его метод execute() для выполнения SQL-команд:

c = conn.cursor()

# Создать таблицу
c.execute('''CREATE TABLE stocks
             (date text, trans text, symbol text, qty real, price real)''')

# Вставить строку данных
c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")

# Сохранить (зафиксировать) изменения
conn.commit()

# Также можно закрыть соединение, если работа с ним завершена.
# Все изменения должны быть зафиксированы, иначе они будут потеряны.
conn.close()

Сохранённые данные являются постоянными и доступны в последующих сеансах:

import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()

Обычно в SQL-операциях требуется использовать значения из переменных Python. Не следует собирать запрос с помощью строковых операций Python, потому что это небезопасно; это делает программу уязвимой для атак SQL-инъекций (см. https://xkcd.com/327/ – забавный пример того, что может пойти не так).

Вместо этого используется подстановка параметров DB-API. ? ставится в качестве заполнителя там, где требуется значение, после чего кортеж значений передаётся вторым аргументом методу execute() курсора. (Другие модули баз данных могут использовать другой заполнитель, например %s или :1.) Например:

# Никогда не делайте этого – это небезопасно!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

# Вместо этого сделайте так
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()

# Более крупный пример, вставляющий много записей за один раз
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)

Чтобы получить данные после выполнения запроса SELECT, можно либо рассматривать курсор как итератор, вызвать метод fetchone() курсора для получения одной подходящей строки, либо вызвать fetchall() для получения списка подходящих строк.

В этом примере используется форма итератора:

>>> for row in c.execute('SELECT * FROM stocks ORDER BY price'):
        print row

(u'2006-01-05', u'BUY', u'RHAT', 100, 35.14)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSFT', 1000, 72.0)

См. также

https://github.com/ghaering/pysqlite

Страница pysqlite – sqlite3 разрабатывается отдельно под названием «pysqlite».

https://www.sqlite.org

Веб-страница SQLite; документация описывает синтаксис и доступные типы данных поддерживаемого диалекта SQL.

http://www.w3schools.com/sql/

Учебные материалы, справочник и примеры для изучения синтаксиса SQL.

PEP 249 – спецификация API баз данных 2.0

PEP написан Марком-Андре Лембургом.

11.13.1. Функции и константы модуляModule functions and constants

sqlite3.version

Номер версии этого модуля в виде строки. Это не версия библиотеки SQLite.

sqlite3.version_info

Номер версии этого модуля в виде кортежа целых чисел. Это не версия библиотеки SQLite.

sqlite3.sqlite_version

Номер версии библиотеки SQLite времени выполнения в виде строки.

sqlite3.sqlite_version_info

Номер версии библиотеки SQLite времени выполнения в виде кортежа целых чисел.

sqlite3.PARSE_DECLTYPES

Эта константа предназначена для использования с параметром detect_types функции connect().

Установка этого флага заставляет модуль sqlite3 анализировать объявленный тип для каждого возвращаемого столбца. Он выделит первое слово объявленного типа, т. е. для «integer primary key» выделит «integer», а для «number(10)» выделит «number». Затем для этого столбца он заглянет в словарь преобразователей и использует зарегистрированную там функцию преобразования для этого типа.

sqlite3.PARSE_COLNAMES

Эта константа предназначена для использования с параметром detect_types функции connect().

Установка этого параметра заставляет интерфейс SQLite разбирать имена столбцов для каждого столбца, который он возвращает. Он будет искать строку вида [mytype] и на основании этого определять, что 'mytype' – это тип столбца. Затем он попытается найти запись 'mytype' в словаре конвертеров и использовать найденную функцию-конвертер для возврата значения. Имя столбца, найденное в Cursor.description, – это только первое слово имени столбца; то есть если используется что-то вроде 'as "x [datetime]"' в SQL, то будет извлечено всё до первого пробела: именем столбца будет просто "x".

sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements])

Открывает соединение с файлом базы данных SQLite database. Можно использовать ":memory:" для открытия соединения с базой данных, которая находится в оперативной памяти, вместо файла на диске.

Когда к базе данных обращаются несколько соединений и один из процессов изменяет базу данных, база данных SQLite блокируется до завершения этой транзакции. Параметр timeout задаёт, как долго соединение должно ждать снятия блокировки, прежде чем возникнет исключение. Значение по умолчанию для параметра timeout – 5.0 (пять секунд).

По поводу параметра isolation_level обратитесь к свойству Connection.isolation_level объектов Connection.

SQLite изначально поддерживает только типы TEXT, INTEGER, REAL, BLOB и NULL. Если вы хотите использовать другие типы, необходимо добавить поддержку самостоятельно. Параметр detect_types и использование пользовательских преобразователей, зарегистрированных с помощью функции модуля register_converter(), позволяют легко это сделать.

detect_types по умолчанию равен 0 (т.е. выключен, определение типов не выполняется). Вы можете установить его в любую комбинацию PARSE_DECLTYPES и PARSE_COLNAMES, чтобы включить определение типов.

По умолчанию модуль sqlite3 использует свой класс Connection для вызова connect. Однако вы можете создать подкласс класса Connection и заставить connect() использовать ваш класс, передав его в параметре factory.

Подробности см. в разделе Типы SQLite и Python данного руководства.

Модуль sqlite3 внутренне использует кэш операторов для снижения накладных расходов на разбор SQL. Если вы хотите явно задать количество операторов, кэшируемых для соединения, можно установить параметр cached_statements. Текущая реализация по умолчанию кэширует 100 операторов.

sqlite3.register_converter(typename, callable)

Регистрирует вызываемый объект для преобразования байтовой строки из базы данных в пользовательский тип Python. Вызываемый объект будет вызываться для всех значений базы данных, имеющих тип typename. Смотрите параметр detect_types функции connect(), чтобы узнать, как работает определение типа. Обратите внимание, что typename и имя типа в запросе сравниваются без учёта регистра.

sqlite3.register_adapter(type, callable)

Регистрирует вызываемый объект для преобразования пользовательского типа Python type в один из поддерживаемых типов SQLite. Вызываемый объект callable принимает в качестве единственного параметра значение Python и должен возвращать значение одного из следующих типов: int, long, float, str (в кодировке UTF-8), unicode или buffer.

sqlite3.complete_statement(sql)

Возвращает True, если строка sql содержит одно или несколько полных SQL-выражений, завершающихся точкой с запятой. При этом не проверяется синтаксическая корректность SQL, только отсутствие незакрытых строковых литералов и завершение выражения точкой с запятой.

Это можно использовать для создания оболочки для SQLite, как в следующем примере:

# Минимальная оболочка SQLite для экспериментов

import sqlite3

con = sqlite3.connect(":memory:")
con.isolation_level = None
cur = con.cursor()

buffer = ""

print "Enter your SQL commands to execute in sqlite3."
print "Enter a blank line to exit."

while True:
    line = raw_input()
    if line == "":
        break
    buffer += line
    if sqlite3.complete_statement(buffer):
        try:
            buffer = buffer.strip()
            cur.execute(buffer)

            if buffer.lstrip().upper().startswith("SELECT"):
                print cur.fetchall()
        except sqlite3.Error as e:
            print "An error occurred:", e.args[0]
        buffer = ""

con.close()
sqlite3.enable_callback_tracebacks(flag)

По умолчанию трассировки не отображаются для пользовательских функций, агрегатов, преобразователей, колбэков авторизатора и т.д. Для отладки можно вызвать эту функцию, установив для flag значение True. После этого трассировки будут отображаться из колбэков на sys.stderr. Используйте False, чтобы снова отключить эту возможность.

11.13.2. Объекты соединенийConnection Objects

class sqlite3.Connection

Соединение с базой данных SQLite обладает следующими атрибутами и методами:

isolation_level

Возвращает или задаёт текущий уровень изоляции. None для режима автоподтверждения или одно из значений «DEFERRED», «IMMEDIATE» или «EXCLUSIVE». Подробное объяснение см. в разделе Управление транзакциями.

cursor(factory=Cursor)

Метод cursor принимает один необязательный параметр factory. Если он указан, это должен быть вызываемый объект, возвращающий экземпляр Cursor или его подклассов.

commit()

Этот метод фиксирует текущую транзакцию. Если не вызвать этот метод, все изменения, сделанные после последнего вызова commit(), не будут видны из других подключений к базе данных. Если вы не видите данные, которые записали в базу, проверьте, не забыли ли вызвать этот метод.

rollback()

Этот метод откатывает все изменения в базе данных, сделанные после последнего вызова commit().

close()

Это закрывает подключение к базе данных. Обратите внимание, что это не вызывает автоматически commit(). Если просто закрыть подключение к базе данных, не вызвав предварительно commit(), изменения будут потеряны!

execute(sql[, parameters])

Это нестандартное сокращение, которое создаёт промежуточный объект курсора путём вызова метода cursor, а затем вызывает метод execute курсора с переданными параметрами.

executemany(sql[, parameters])

Это нестандартное сокращение, которое создаёт промежуточный объект курсора путём вызова метода cursor, а затем вызывает метод executemany курсора с переданными параметрами.

executescript(sql_script)

Это нестандартное сокращение, которое создаёт промежуточный объект курсора путём вызова метода cursor, а затем вызывает метод executescript курсора с переданными параметрами.

create_function(name, num_params, func)

Создаёт пользовательскую функцию, которую затем можно использовать в SQL-выражениях под именем name. num_params – количество параметров, принимаемых функцией, а func – вызываемый объект Python, который будет вызываться как SQL-функция.

Функция может возвращать любой из типов, поддерживаемых SQLite: unicode, str, int, long, float, buffer и None.

Пример:

import sqlite3
import md5

def md5sum(t):
    return md5.md5(t).hexdigest()

con = sqlite3.connect(":memory:")
con.create_function("md5", 1, md5sum)
cur = con.cursor()
cur.execute("select md5(?)", ("foo",))
print cur.fetchone()[0]
create_aggregate(name, num_params, aggregate_class)

Создаёт пользовательскую агрегатную функцию.

Класс агрегатной функции должен реализовывать метод step, который принимает количество параметров num_params, и метод finalize, который будет возвращать окончательный результат агрегации.

Метод finalize может возвращать любой из типов, поддерживаемых SQLite: unicode, str, int, long, float, buffer и None.

Пример:

import sqlite3

class MySum:
    def __init__(self):
        self.count = 0

    def step(self, value):
        self.count += value

    def finalize(self):
        return self.count

con = sqlite3.connect(":memory:")
con.create_aggregate("mysum", 1, MySum)
cur = con.cursor()
cur.execute("create table test(i)")
cur.execute("insert into test(i) values (1)")
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print cur.fetchone()[0]
create_collation(name, callable)

Создаёт collation с указанными name и callable. Вызываемый объект будет получать два строковых аргумента. Он должен возвращать -1, если первый меньше второго, 0, если они равны, и 1, если первый больше второго. Обратите внимание, что это управляет сортировкой (ORDER BY в SQL), поэтому сравнения не влияют на другие операции SQL.

Обратите внимание, что вызываемый объект будет получать свои параметры в виде байтовых строк Python, которые обычно закодированы в UTF-8.

Следующий пример показывает пользовательскую коллацию, которая сортирует «в обратном порядке»:

import sqlite3

def collate_reverse(string1, string2):
    return -cmp(string1, string2)

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)

cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
    print row
con.close()

Чтобы удалить коллацию, вызовите create_collation с None в качестве вызываемого объекта:

con.create_collation("reverse", None)
interrupt()

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

set_authorizer(authorizer_callback)

Эта процедура регистрирует колбэк. Колбэк вызывается при каждой попытке доступа к столбцу таблицы в базе данных. Колбэк должен возвращать SQLITE_OK, если доступ разрешён, SQLITE_DENY, если весь SQL-запрос должен быть прерван с ошибкой, и SQLITE_IGNORE, если столбец должен рассматриваться как значение NULL. Эти константы доступны в модуле sqlite3.

Первый аргумент колбэка указывает, какой тип операции требуется авторизовать. Второй и третий аргументы будут аргументами или None в зависимости от первого аргумента. Четвёртый аргумент – имя базы данных («main», «temp» и т.д.), если применимо. Пятый аргумент – имя самого внутреннего триггера или представления, ответственного за попытку доступа, или None, если эта попытка доступа происходит непосредственно из входного SQL-кода.

Обратитесь к документации SQLite за возможными значениями первого аргумента и значением второго и третьего аргументов в зависимости от первого. Все необходимые константы доступны в модуле sqlite3.

set_progress_handler(handler, n)

Эта процедура регистрирует колбэк. Колбэк вызывается каждые n инструкций виртуальной машины SQLite. Это полезно, если требуется получать вызовы от SQLite во время длительных операций, например для обновления графического интерфейса.

Чтобы очистить ранее установленный обработчик прогресса, вызовите метод с None для handler.

Новое в версии 2.6.

enable_load_extension(enabled)

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

Загружаемые расширения по умолчанию отключены. См. 1.

Новое в версии 2.7.

import sqlite3

con = sqlite3.connect(":memory:")

# включить загрузку расширений
con.enable_load_extension(True)

# Загрузить расширение полнотекстового поиска.
con.execute("select load_extension('./fts3.so')")

# в качестве альтернативы можно загрузить расширение с помощью вызова API:
# con.load_extension("./fts3.so")

# отключить загрузку расширения снова
con.enable_load_extension(False)

# пример из вики SQLite
con.execute("create virtual table recipe using fts3(name, ingredients)")
con.executescript("""
    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
    """)
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
    print row
load_extension(path)

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

Загружаемые расширения по умолчанию отключены. См. 1.

Новое в версии 2.7.

row_factory

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

Пример:

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

Если возврата кортежа недостаточно и требуется доступ к столбцам по имени, рассмотрите возможность установки row_factory в высокооптимизированный тип sqlite3.Row. Row обеспечивает как доступ по индексу, так и регистронезависимый доступ по имени с почти нулевыми накладными расходами памяти. Вероятно, это будет лучше, чем собственное решение на основе словаря или даже на основе db_row.

text_factory

С помощью этого атрибута можно управлять тем, какие объекты возвращаются для типа данных TEXT. По умолчанию этот атрибут имеет значение unicode, и модуль sqlite3 возвращает объекты Unicode для TEXT. Если вместо этого нужно возвращать байтовые строки, можно установить значение str.

Из соображений эффективности существует также способ возвращать объекты Unicode только для не-ASCII данных, а в остальных случаях – байтовые строки. Чтобы активировать это, установите данный атрибут в sqlite3.OptimizedUnicode.

Также можно установить его в любой другой вызываемый объект, принимающий единственный параметр – байтовую строку и возвращающий результирующий объект.

См. следующий пример для иллюстрации:

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()

AUSTRIA = u"\xd6sterreich"

# по умолчанию строки возвращаются как Unicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert row[0] == AUSTRIA

# но можно заставить sqlite3 всегда возвращать байтовые строки...
con.text_factory = str
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) is str
# байтовые строки будут в кодировке UTF-8, если только в базу не попал мусор
# база данных...
assert row[0] == AUSTRIA.encode("utf-8")

# можно также реализовать собственный text_factory...
# здесь мы реализуем такой, который будет игнорировать символы Unicode, которые не могут быть
# декодированы из UTF-8
con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
cur.execute("select ?", ("this is latin1 and would normally create errors" +
                         u"\xe4\xf6\xfc".encode("latin1"),))
row = cur.fetchone()
assert type(row[0]) is unicode

# sqlite3 предлагает встроенную оптимизированную text_factory, которая возвращает байтовые строки
# объекты, если данные только в ASCII, и в противном случае возвращает объекты Unicode
con.text_factory = sqlite3.OptimizedUnicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) is unicode

cur.execute("select ?", ("Germany",))
row = cur.fetchone()
assert type(row[0]) is str
total_changes

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

iterdump

Возвращает итератор для дампа базы данных в текстовом формате SQL. Полезно при сохранении базы данных в памяти для последующего восстановления. Эта функция предоставляет те же возможности, что и команда .dump в оболочке sqlite3.

Новое в версии 2.6.

Пример:

# Преобразовать файл existing_db.db в SQL-дамп dump.sql
import sqlite3, os

con = sqlite3.connect('existing_db.db')
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write('%s\n' % line)

11.13.3. Объекты курсораCursor Objects

class sqlite3.Cursor

Экземпляр Cursor имеет следующие атрибуты и методы.

execute(sql[, parameters])

Выполняет SQL-выражение. SQL-выражение может быть параметризованным (т. е. с использованием плейсхолдеров вместо литералов SQL). Модуль sqlite3 поддерживает два вида плейсхолдеров: вопросительные знаки (стиль qmark) и именованные плейсхолдеры (именованный стиль).

Вот пример обоих стилей:

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table people (name_last, age)")

who = "Yeltsin"
age = 72

# Это стиль qmark:
cur.execute("insert into people values (?, ?)", (who, age))

# А это именованный стиль:
cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age})

print cur.fetchone()

execute() выполнит только один SQL-оператор. Если попытаться выполнить им более одного оператора, будет возбуждено предупреждение (Warning). Используйте executescript(), если требуется выполнить несколько SQL-операторов за один вызов.

executemany(sql, seq_of_parameters)

Выполняет SQL-команду для всех последовательностей или отображений параметров, найденных в последовательности sql. Модуль sqlite3 также позволяет использовать итератор, возвращающий параметры, вместо последовательности.

import sqlite3

class IterChars:
    def __init__(self):
        self.count = ord('a')

    def __iter__(self):
        return self

    def next(self):
        if self.count > ord('z'):
            raise StopIteration
        self.count += 1
        return (chr(self.count - 1),) # это кортеж из одного элемента

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)

cur.execute("select c from characters")
print cur.fetchall()

Вот более короткий пример с использованием генератора:

import sqlite3
import string

def char_generator():
    for c in string.lowercase:
        yield (c,)

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

cur.executemany("insert into characters(c) values (?)", char_generator())

cur.execute("select c from characters")
print cur.fetchall()
executescript(sql_script)

Это нестандартный удобный метод для выполнения нескольких SQL-выражений за один раз. Сначала он выполняет оператор COMMIT, а затем выполняет SQL-скрипт, переданный в качестве параметра.

sql_script может быть байтовой строкой или строкой Unicode.

Пример:

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
    create table person(
        firstname,
        lastname,
        age
    );

    create table book(
        title,
        author,
        published
    );

    insert into book(title, author, published)
    values (
        'Dirk Gently''s Holistic Detective Agency',
        'Douglas Adams',
        1987
    );
    """)
fetchone()

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

fetchmany([size=cursor.arraysize])

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

Количество строк, извлекаемых за один вызов, задаётся параметром size. Если он не указан, количество строк определяется атрибутом arraysize курсора. Метод должен пытаться извлечь столько строк, сколько указано параметром size. Если это невозможно из-за того, что указанное количество строк недоступно, может быть возвращено меньше строк.

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

fetchall()

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

rowcount

Хотя класс Cursor модуля sqlite3 реализует этот атрибут, собственная поддержка определения «затронутых строк»/«выбранных строк» в движке базы данных работает непредсказуемо.

Для выражений executemany() количество изменений суммируется в rowcount.

В соответствии со спецификацией Python DB API, атрибут rowcount «равен -1, если над курсором не выполнялось executeXX() или количество строк последней операции не может быть определено интерфейсом». Это включает выражения SELECT, потому что количество строк, полученных запросом, нельзя определить, пока не будут извлечены все строки.

В SQLite версий до 3.6.5 rowcount устанавливается в 0, если выполнить DELETE FROM table без условия.

lastrowid

Этот атрибут только для чтения возвращает rowid последней изменённой строки. Он устанавливается только при выполнении оператора INSERT с помощью метода execute(). Для операций, отличных от INSERT, или при вызове executemany(), lastrowid устанавливается в None.

description

Этот атрибут только для чтения содержит имена столбцов последнего запроса. Для совместимости с Python DB API он возвращает 7-кортеж для каждого столбца, где последние шесть элементов каждого кортежа равны None.

Он также устанавливается для операторов SELECT, не имеющих подходящих строк.

connection

Этот атрибут только для чтения предоставляет Connection базы данных SQLite, используемый объектом Cursor. Объект Cursor, созданный вызовом con.cursor(), будет иметь атрибут connection, ссылающийся на con:

>>> con = sqlite3.connect(":memory:")
>>> cur = con.cursor()
>>> cur.connection == con
True

11.13.4. Объекты строкRow Objects

class sqlite3.Row

Экземпляр Row служит высокооптимизированной row_factory для объектов Connection. Он старается имитировать кортеж в большинстве своих возможностей.

Он поддерживает доступ по имени столбца и индексу, итерацию, представление, проверку равенства и len().

Если два объекта Row имеют одинаковые столбцы и их члены равны, они считаются равными.

Изменено в версии 2.6: Добавлена итерация и поддержка проверки на равенство (хешируемость).

keys()

Этот метод возвращает список имён столбцов. Сразу после запроса это первый элемент каждого кортежа в Cursor.description.

Новое в версии 2.6.

Предположим, мы инициализируем таблицу, как в приведённом выше примере:

conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")
conn.commit()
c.close()

Теперь подключаем Row:

>>> conn.row_factory = sqlite3.Row
>>> c = conn.cursor()
>>> c.execute('select * from stocks')
<sqlite3.Cursor object at 0x7f4e7dd8fa80>
>>> r = c.fetchone()
>>> type(r)
<type 'sqlite3.Row'>
>>> r
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14)
>>> len(r)
5
>>> r[2]
u'RHAT'
>>> r.keys()
['date', 'trans', 'symbol', 'qty', 'price']
>>> r['qty']
100.0
>>> for member in r:
...     print member
...
2006-01-05
BUY
RHAT
100.0
35.14

11.13.5. Типы SQLite и PythonSQLite and Python types

11.13.5.1. ВведениеIntroduction

SQLite изначально поддерживает следующие типы: NULL, INTEGER, REAL, TEXT, BLOB.

Следующие типы Python можно передавать в SQLite без каких-либо проблем:

Тип Python

Тип SQLite

None

NULL

int

INTEGER

long

INTEGER

float

REAL

str (в кодировке UTF-8)

TEXT

unicode

TEXT

buffer

BLOB

Так по умолчанию типы SQLite преобразуются в типы Python:

Тип SQLite

Тип Python

NULL

None

INTEGER

int или long, в зависимости от размера

REAL

float

TEXT

зависит от text_factory, по умолчанию unicode

BLOB

buffer

Система типов модуля sqlite3 расширяема двумя способами: можно хранить дополнительные типы Python в базе данных SQLite с помощью адаптации объектов, а также можно позволить модулю sqlite3 преобразовывать типы SQLite в различные типы Python с помощью конвертеров.

11.13.5.2. Использование адаптеров для хранения дополнительных типов Python в базах данных SQLiteUsing adapters to store additional Python types in SQLite databases

Как было сказано ранее, SQLite изначально поддерживает лишь ограниченный набор типов. Чтобы использовать другие типы Python с SQLite, необходимо адаптировать их к одному из поддерживаемых модулем sqlite3 типов SQLite: NoneType, int, long, float, str, unicode, buffer.

Существует два способа разрешить модулю sqlite3 адаптировать пользовательский тип Python к одному из поддерживаемых.

11.13.5.2.1. Самостоятельная адаптация объектаLetting your object adapt itself

Это хороший подход, если вы пишете класс сами. Предположим, у вас есть такой класс:

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

Теперь нужно сохранить точку в одном столбце SQLite. Сначала нужно выбрать один из поддерживаемых типов для представления точки. Давайте просто используем str и разделим координаты точкой с запятой. Затем нужно определить в классе метод __conform__(self, protocol), который должен возвращать преобразованное значение. Параметр протокол будет равен PrepareProtocol.

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __conform__(self, protocol):
        if protocol is sqlite3.PrepareProtocol:
            return "%f;%f" % (self.x, self.y)

con = sqlite3.connect(":memory:")
cur = con.cursor()

p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]

11.13.5.2.2. Регистрация вызываемого адаптераRegistering an adapter callable

Другой вариант – создать функцию, которая преобразует тип в строковое представление, и зарегистрировать её с помощью register_adapter().

Примечание

Адаптируемый тип/класс должен быть классом нового стиля, т. е. он должен иметь object в качестве одного из своих базовых классов.

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

def adapt_point(point):
    return "%f;%f" % (point.x, point.y)

sqlite3.register_adapter(Point, adapt_point)

con = sqlite3.connect(":memory:")
cur = con.cursor()

p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]

Модуль sqlite3 имеет два адаптера по умолчанию для встроенных типов Python datetime.date и datetime.datetime. Теперь предположим, что мы хотим сохранить объекты datetime.datetime не в формате ISO, а в виде временной метки Unix.

import sqlite3
import datetime, time

def adapt_datetime(ts):
    return time.mktime(ts.timetuple())

sqlite3.register_adapter(datetime.datetime, adapt_datetime)

con = sqlite3.connect(":memory:")
cur = con.cursor()

now = datetime.datetime.now()
cur.execute("select ?", (now,))
print cur.fetchone()[0]

11.13.5.3. Преобразование значений SQLite в пользовательские типы PythonConverting SQLite values to custom Python types

Написание адаптера позволяет отправлять пользовательские типы Python в SQLite. Но чтобы сделать это действительно полезным, нужно обеспечить обратное преобразование из SQLite в Python.

Вступают конвертеры.

Вернемся к классу Point. Мы сохраняли координаты x и y, разделенные точкой с запятой, в виде строк в SQLite.

Сначала определим функцию-конвертер, которая принимает строку в качестве параметра и создает из нее объект Point.

Примечание

Функции преобразования всегда вызываются со строкой, независимо от того, под каким tипом данных значение было отправлено в SQLite.

def convert_point(s):
    x, y = map(float, s.split(";"))
    return Point(x, y)

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

  • Неявно, через объявленный тип

  • Явно, по имени колонки

Оба способа описаны в разделе Функции и константы модуля, в записях для констант PARSE_DECLTYPES и PARSE_COLNAMES.

Следующий пример иллюстрирует оба подхода.

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __repr__(self):
        return "(%f;%f)" % (self.x, self.y)

def adapt_point(point):
    return "%f;%f" % (point.x, point.y)

def convert_point(s):
    x, y = map(float, s.split(";"))
    return Point(x, y)

# Зарегистрировать адаптер
sqlite3.register_adapter(Point, adapt_point)

# Зарегистрировать конвертер
sqlite3.register_converter("point", convert_point)

p = Point(4.0, -3.2)

#########################
# 1) Использование объявленных типов
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute("create table test(p point)")

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("select p from test")
print "with declared types:", cur.fetchone()[0]
cur.close()
con.close()

#######################
# 1) Использование имён столбцов
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(p)")

cur.execute("insert into test(p) values (?)", (p,))
cur.execute('select p as "p [point]" from test')
print "with column names:", cur.fetchone()[0]
cur.close()
con.close()

11.13.5.4. Адаптеры и конвертеры по умолчаниюDefault adapters and converters

В модуле datetime есть адаптеры по умолчанию для типов date и datetime. Они отправляются в SQLite как даты/временные метки в формате ISO.

Преобразователи по умолчанию зарегистрированы под именем «date» для datetime.date и под именем «timestamp» для datetime.datetime.

Таким образом, в большинстве случаев можно использовать даты и временные метки из Python без лишних усилий. Формат адаптеров также совместим с экспериментальными функциями даты/времени SQLite.

Следующий пример демонстрирует это.

import sqlite3
import datetime

con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(d date, ts timestamp)")

today = datetime.date.today()
now = datetime.datetime.now()

cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
cur.execute("select d, ts from test")
row = cur.fetchone()
print today, "=>", row[0], type(row[0])
print now, "=>", row[1], type(row[1])

cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
row = cur.fetchone()
print "current_date", row[0], type(row[0])
print "current_timestamp", row[1], type(row[1])

Если временная метка, хранящаяся в SQLite, имеет дробную часть длиннее 6 знаков, её значение будет усечено до микросекундной точности преобразователем временных меток.

11.13.6. Управление транзакциямиControlling Transactions

По умолчанию модуль sqlite3 неявно начинает транзакции перед инструкцией языка манипулирования данными (DML) (т.е. INSERT/UPDATE/DELETE/REPLACE) и неявно фиксирует транзакции перед инструкцией, не являющейся DML и не являющейся запросом (т.е. любой, кроме SELECT или упомянутых выше).

Итак, если внутри транзакции выполняется команда вроде CREATE TABLE ..., VACUUM, PRAGMA, модуль sqlite3 неявно выполнит commit перед выполнением этой команды. Для этого есть две причины. Первая: некоторые из этих команд не работают внутри транзакций. Вторая: sqlite3 необходимо отслеживать состояние транзакции (активна транзакция или нет).

Вы можете управлять тем, какие инструкции BEGIN sqlite3 неявно выполняет (или не выполняет вовсе) с помощью параметра isolation_level вызова connect() или с помощью свойства isolation_level соединений.

Если вам нужен режим автоматической фиксации, установите isolation_level в None.

В противном случае оставьте его по умолчанию, что приведет к простой инструкции “BEGIN”, или установите одно из поддерживаемых уровней изоляции SQLite: “DEFERRED”, “IMMEDIATE” или “EXCLUSIVE”.

11.13.7. Эффективное использование sqlite3Using sqlite3 efficiently

11.13.7.1. Использование сокращённых методовUsing shortcut methods

Используя нестандартные методы execute(), executemany() и executescript() объекта Connection, код можно писать более кратко, поскольку не нужно явно создавать (часто излишние) объекты Cursor. Вместо этого объекты Cursor создаются неявно, и эти сокращенные методы возвращают объекты курсора. Таким образом, можно выполнить оператор SELECT и итерироваться по нему напрямую, используя всего один вызов объекта Connection.

import sqlite3

persons = [
    ("Hugo", "Boss"),
    ("Calvin", "Klein")
    ]

con = sqlite3.connect(":memory:")

# Создать таблицу
con.execute("create table person(firstname, lastname)")

# Заполнить таблицу
con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)

# Выводит содержимое таблицы.
for row in con.execute("select firstname, lastname from person"):
    print row

print "I just deleted", con.execute("delete from person").rowcount, "rows"

11.13.7.2. Доступ к столбцам по имени вместо индексаAccessing columns by name instead of by index

Одна из полезных возможностей модуля sqlite3 – встроенный класс sqlite3.Row, предназначенный для использования в качестве фабрики строк.

Строки, обёрнутые этим классом, можно получать как по индексу (как кортежи), так и по имени без учёта регистра:

import sqlite3

con = sqlite3.connect(":memory:")
con.row_factory = sqlite3.Row

cur = con.cursor()
cur.execute("select 'John' as name, 42 as age")
for row in cur:
    assert row[0] == row["name"]
    assert row["name"] == row["nAmE"]
    assert row[1] == row["age"]
    assert row[1] == row["AgE"]

11.13.7.3. Использование соединения в качестве менеджера контекстаUsing the connection as a context manager

Новое в версии 2.6.

Объекты соединения можно использовать как менеджеры контекста, которые автоматически фиксируют или откатывают транзакции. В случае исключения транзакция откатывается; в противном случае транзакция фиксируется:

import sqlite3

con = sqlite3.connect(":memory:")
con.execute("create table person (id integer primary key, firstname varchar unique)")

# При успешном выполнении con.commit() вызывается автоматически.
with con:
    con.execute("insert into person(firstname) values (?)", ("Joe",))

# con.rollback() вызывается после завершения блока with с исключением,
# исключение все равно возбуждается, и его необходимо перехватить
try:
    with con:
        con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
    print "couldn't add Joe twice"

11.13.8. Часто встречающиеся проблемыCommon issues

11.13.8.1. МногопоточностьMultithreading

В старых версиях SQLite были проблемы с совместным использованием соединений между потоками. Именно поэтому модуль Python запрещает совместное использование соединений и курсоров между потоками. Если всё же попытаться это сделать, во время выполнения будет возбуждено исключение.

Единственное исключение – вызов метода interrupt(), который имеет смысл вызывать только из другого потока.

Сноски

1(1,2)

Модуль sqlite3 по умолчанию собирается без поддержки загружаемых расширений, так как на некоторых платформах (в частности, Mac OS X) библиотеки SQLite скомпилированы без этой возможности. Чтобы включить поддержку загружаемых расширений, необходимо изменить setup.py и удалить строку, устанавливающую SQLITE_OMIT_LOAD_EXTENSION.