В существующем проекте сохраняется пользовательский класс в колонку таблицы (как скаляр), используя встроенные механизмы sqlite3. Таким же образом сохраняется дата. Пример на базе документации sqlite3
import sqlite3
from datetime import date
import noorm.sqlite3 as nm
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x},{self.y})"
def __conform__(self, protocol):
if protocol is sqlite3.PrepareProtocol:
return f"{self.x};{self.y}"
def convert_point(s):
coord = map(float, s.split(b";"))
return Point(*coord)
sqlite3.register_converter("point", convert_point)
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.execute("CREATE TABLE test(p point, p_date date)")
p = Point(4.0, -3.2)
p_date = date.today()
cur.execute("INSERT INTO test(p, p_date) VALUES(?, ?)", (p, p_date))
cur.execute("SELECT p, p_date FROM test")
print("with declared types:", cur.fetchone())
#>> with declared types: (Point(4.0,-3.2), datetime.date(2024, 8, 4))
Решив использовать noorm, при вызове
@nm.sql_fetch_scalars(date, "SELECT p_date FROM test")
def all_date():
...
print(all_date(con))
получу ошибку TypeError: fromisoformat: argument must be str из-за дополнительного преобразования уже преобразованной драйвером в дату строки.
Если выключить конвертацию драйвером, даты будут преобразованы библиотекой, но она ничего не знает про восстановление пользовательского объекта — вернёт строку '4.0;-3.2'
Можно использовать PARSE_COLNAMES, но а) запрос выглядит некрасиво p AS "p [point]" и б) это надо не забывать дублировать в каждом запросе, где участвует поле point.
P.S. Хороший аргумент для issue #6 Discussion of using type hints for return data. Возможность задать параметр `scalar=True' действительно нужна, для перекрытия автоматики.
В существующем проекте сохраняется пользовательский класс в колонку таблицы (как скаляр), используя встроенные механизмы sqlite3. Таким же образом сохраняется дата. Пример на базе документации sqlite3
Решив использовать
noorm
, при вызовеполучу ошибку
TypeError: fromisoformat: argument must be str
из-за дополнительного преобразования уже преобразованной драйвером в дату строки. Если выключить конвертацию драйвером, даты будут преобразованы библиотекой, но она ничего не знает про восстановление пользовательского объекта — вернёт строку'4.0;-3.2'
Можно использовать PARSE_COLNAMES, но а) запрос выглядит некрасиво
p AS "p [point]"
и б) это надо не забывать дублировать в каждом запросе, где участвует поле point.P.S. Хороший аргумент для issue #6 Discussion of using type hints for return data. Возможность задать параметр `scalar=True' действительно нужна, для перекрытия автоматики.