SQL ORM-mixin-ы и коллекции#
Модуль: restalchemy.storage.sql.orm
Модуль предоставляет ORM-подобное поведение для DM-моделей:
ObjectCollection— коллекция объектов, доступная какModel.objects.SQLStorableMixin— mixin, добавляющийsave(),update(),delete()и интеграцию с SQL-таблицами.SQLStorableWithJSONFieldsMixin— специализация для моделей с JSON-полями.
ObjectCollection#
ObjectCollection реализует интерфейс коллекции для моделей, хранимых в SQL.
Ключевые методы:
get_all(filters=None, session=None, cache=False, limit=None, order_by=None, locked=False)- Возвращает список экземпляров модели.
- Использует
filters(структуры изrestalchemy.dm.filters) для построения WHERE-условий. - При
cache=Trueиспользует кэш запросов на уровне сессии. get_one(filters=None, session=None, cache=False, locked=False)- Возвращает ровно одну запись.
- Бросает
RecordNotFound, если записей нет, иHasManyRecords, если более одной. get_one_or_none(filters=None, session=None, cache=False, locked=False)- Возвращает одну запись или
None, если ничего не найдено. query(where_conditions, where_values, session=None, cache=False, limit=None, order_by=None, locked=False)- Выполняет кастомный SELECT с произвольным WHERE.
count(session=None, filters=None)- Возвращает количество записей, удовлетворяющих фильтру.
ObjectCollection использует:
- Диалект SQL через
engine.dialect. - Метод модели
restore_from_storage()для конвертации строк из БД в DM-модели.
Загрузка связей#
Связь, которую запрос не прочитал вместе со строкой (prefetch), приходит
идентификатором, и модель, которую он называет, читается отдельно. get_all()
и query() собирают идентификаторы всей страницы и читают их одним запросом на
связь, а не одним запросом на строку, и так же поступают с тем, на что
указывают уже прочитанные объекты.
- Строки страницы, называющие один и тот же объект, получают один и тот же экземпляр.
- Идентификатор, которого страница не нашла, остаётся как есть, поэтому строка, указывающая на отсутствующую запись, падает ровно так же, как падала раньше.
- Связь, объявленная с
prefetch=True, читается тем же запросом, что и страница (LEFT JOIN), и в этом не участвует. SQLStorableMixin.RELATIONSHIP_BATCH_SIZE(по умолчанию 1000) ограничивает количество идентификаторов в одном запросе.
SQLStorableMixin#
SQLStorableMixin используется совместно с DM-моделями для их хранения в SQL.
Требования#
- Модель должна иметь строковый атрибут
__tablename__. - Должно быть хотя бы одно ID-свойство (
id_property=True).
Ответственность#
get_table()- Возвращает объект
SQLTableдля модели, кэшируемый в__operational_storage__. insert(session=None)- Выполняет INSERT на основе текущих значений свойств.
save(session=None)- Вызывает
insert()для новых объектов иupdate()для уже сохранённых. update(session=None, force=False)- Обновляет строку, если модель "грязная" (
is_dirty()) илиforce=True. - Перед обновлением вызывает
validate(). - Гарантирует, что обновлена ровно одна строка, иначе бросает исключение.
delete(session=None)- Удаляет строку по ID-свойствам.
restore_from_storage(**kwargs)(classmethod)- Преобразует значения из БД (простые типы) в значения DM-свойств.
- Создаёт экземпляр модели, помеченный как "сохранённый".
Привязка коллекции объектов#
SQLStorableMixin определяет _ObjectCollection = ObjectCollection. В комбинации с базовыми классами storage это даёт:
Model.objects— коллекцию, работающую черезObjectCollection.
Помощники преобразований типов#
to_simple_type(value)(classmethod)- Конвертирует экземпляры модели или "сырые" ID в вид, пригодный для фильтров.
from_simple_type(value)(classmethod)- Конвертирует ID или результат prefetch в экземпляр модели.
SQLStorableWithJSONFieldsMixin#
SQLStorableWithJSONFieldsMixin расширяет SQLStorableMixin для БД без нативной поддержки JSON-полей.
Паттерн использования:
- Наследуемся от
SQLStorableWithJSONFieldsMixinвместоSQLStorableMixin. - Определяем
__jsonfields__как перечень имён полей с JSON-данными.
Поведение:
restore_from_storage()- Для полей из
__jsonfields__, если хранимое значение — строка, парсит его как JSON. _get_prepared_data(properties=None)- Для полей из
__jsonfields__сериализует Python-структуры в компактные JSON-строки.
Это позволяет использовать JSON-поля в DM-модели и хранить их как текст в БД, не поддерживающей JSON нативно.