На этом шаге мы рассмотрим способы задания и использования функций, используемых для преобразования данных.
SQLite поддерживает пять типов данных, для каждого из которых в модуле sqlite3 определено соответствие с типом данных Python:
Если необходимо сохранить в таблице данные, которые имеют тип, не поддерживаемый SQLite, то следует преобразовать тип самостоятельно. Для этого с помощью функции register_adapter() можно зарегистрировать пользовательскую функцию, которая будет вызываться при попытке вставки объекта в SQL-запрос. Функция имеет следующий формат:
register_adapter (<Тип данных или класс>, <Ссылка на функцию>)
В первом параметре указывается тип данных или ссылка на класс. Во втором параметре задается ссылка на функцию, которая будет вызываться для преобразования типа. Функция принимает один параметр и должна возвращать значение, имеющее тип данных, поддерживаемый SQLite. Для примера создадим новую таблицу и сохраним в ней значения атрибутов класса:
# -*- coding: utf-8 -*- import sqlite3 class Car: def __init__(self, model, color): self.model, self.color = model, color def my_adapter(car): return "{0}|{1}".format(car.model, car.color) # Регистрируем функцию для преобразования типа sqlite3.register_adapter(Car, my_adapter) # Создаем экземпляр класса Car car = Car("BA3-2109", "красный") con = sqlite3.connect("catalog.db") cur = con.cursor() try: cur.execute("CREATE TABLE cars1 (model TEXT)") cur.execute("INSERT INTO cars1 VALUES (?)", (car,)) except sqlite3.DatabaseError as err: print("Ошибка:", err) else: print("Запрос успешно выполнен") con.commit() cur.close() con.close() input()
Вместо регистрации функции преобразования типа можно внутри класса определить метод __conform__(). Формат метода:
conform (self, <Протокол>)
Параметр Протокол будет соответствовать PrepareProtocol (более подробно о протоколе можно прочитать в документе PEP 246). Метод должен возвращать значение, имеющее тип данных, который поддерживается SQLite. Создадим таблицу cars2 и сохраним в ней значения атрибутов, используя метод __conform__():
# -*- coding: utf-8 -*- import sqlite3 class Car: def __init__(self, model, color): self.model, self.color = model, color def __conform__ (self, protocol): if protocol is sqlite3.PrepareProtocol: return "{0}|{1}".format(car.model, car.color) # Создаем экземпляр класса Car car = Car("Москвич-412", "синий") con = sqlite3.connect("catalog.db") cur = con.cursor() try: cur.execute("CREATE TABLE cars2 (model mycar)") cur.execute("INSERT INTO cars2 VALUES (?)", (car,)) except sqlite3.DatabaseError as err: print("Ошибка:", err) else: print("Запрос успешно выполнен") con.commit() cur.close() con.close() input()
На следующем шаге мы закончим изучение этого вопроса.