Я хотел бы повторно реализовать некоторые из моих существующих моделей SQLAlchemy в хранилище данных только для приложений; append-only означает, что объект обновляется только с помощью инструкций INSERT, а не с помощью операторов UPDATE или DELETE.
Операторы UPDATE и DELETE будут заменены другим INSERT, который увеличивает версию. Будет флаг is_deleted
, а вместо DELETE будет создана новая версия с is_deleted=True
:
id | version | is_deleted | name | description ...
---- --------- ------------ ----------- ---------------
1 | 1 | F | Fo | Text text text.
1 | 2 | F | Foo | Text text text.
2 | 1 | F | Bar | null
1 | 3 | T | Foo | Text text text.
Кроме того,
- Все инструкции SELECT должны быть переписаны только для максимального номера версии для каждого идентификатора, как описано в этом вопросе: PostgreSQL - выборка строки, которая имеет значение Max для столбца
- Все (уникальные) индексы должны быть переписаны как уникальные с помощью первичного ключа "id", так как каждый идентификатор может присутствовать более одного раза.
Я знаю, как решить большинство из этих проблем, но я борюсь с крючками событий в SQLAlchemy, которые будут обрабатывать определенные вещи, которые необходимо выполнить при обновлении и удалении.
В документации SQLAlchemy уже есть некоторые базовые примеры для управления версиями. versioned rows пример близок к тому, что я хочу, но они не обрабатывают (1) удаление и (2) отношения внешних ключей.
(1) Удаление. Я знаю, что есть поле session.deleted
, и я буду перебирать его аналогично тому, как session.dirty
повторяется в versioned_rows.py, но как бы я отменил элемент из списка, который будет удален, и создаст новый элемент?
(2) Вышеупомянутый пример касается только отношения родитель-потомок, и способ его выполнения (с истечением срока действия), по-видимому, требует настраиваемого кода для каждой модели. (2.1) Есть ли способ сделать это более гибким? (2.2) можно ли настроить SQLAlchemy relationship()
для возврата объекта с max (версией) для данного внешнего ключа?