Адаптеры позволяют [отправлять пользовательские типы Python в SQLite. Но чтобы сделать его действительно полезным, нужно заставить работать по схеме Python to SQLite to Python.
Вернемся к классу Point()
, там мы сохранили координаты x
и y
через точку с запятой ';'
в виде строки в базу SQLite.
Во-первых, надо определить функцию-преобразователь, которая принимает строку в качестве параметра и строит из нее объект Point()
.
Примечание. Функции конвертеры всегда вызываются с помощью объекта байтов, независимо от того, в каком типе данных вы отправили значение в SQLite.
def convert_point(s): x, y = map(float, s.split(b";")) return Point(x, y)
Теперь нужно, чтобы модуль sqlite3
знал, то что выбирается из базы данных, на самом деле является точкой. Есть два способа сделать это:
sqlite3.PARSE_DECLTYPES
.sqlite3.PARSE_COLNAMES
.Оба способа описаны в разделе "Сопутствующие функции и константы модуля".
Следующий пример иллюстрирует оба подхода.
import sqlite3 class Point: 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)).encode('ascii') def convert_point(s): x, y = list(map(float, s.split(b";"))) 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()