我想重新实现一些已有的SQLAlchemy模型,使用仅追加的数据存储方式;即只使用INSERT语句更新对象,而不使用UPDATE或DELETE语句。
UPDATE和DELETE语句将被替换为另一个插入语句,该语句将增加版本号。将有一个“is_deleted”标志,而不是DELETE,将创建一个带有“is_deleted=True”的新版本:
此外,需要将所有SELECT语句重写为每个id的最大版本号,具体方法请参考这个问题:PostgreSQL-获取列中最大值的行。还需要将所有(唯一的)索引重写为以" id "主键为唯一标识,因为每个id可能会出现多次。
我知道如何解决大部分的问题,但我在SQLAlchemy中的事件钩子方面遇到了困难,这些事件钩子需要处理某些需要在更新和删除时完成的操作。
SQLAlchemy文档已经提供了一些基本的版本控制示例。 versioned rows 示例接近我想要的内容,但它们不处理 (1) 删除和 (2) 外键关系。
UPDATE和DELETE语句将被替换为另一个插入语句,该语句将增加版本号。将有一个“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语句重写为每个id的最大版本号,具体方法请参考这个问题:PostgreSQL-获取列中最大值的行。还需要将所有(唯一的)索引重写为以" id "主键为唯一标识,因为每个id可能会出现多次。
我知道如何解决大部分的问题,但我在SQLAlchemy中的事件钩子方面遇到了困难,这些事件钩子需要处理某些需要在更新和删除时完成的操作。
SQLAlchemy文档已经提供了一些基本的版本控制示例。 versioned rows 示例接近我想要的内容,但它们不处理 (1) 删除和 (2) 外键关系。
(1) 删除。我知道有一个session.deleted
字段,我会以类似于在versioned_rows.py示例中迭代session.dirty
的方式迭代它——但是如何取消标记要删除的项目并创建一个新项目呢?
(2) 上述示例仅处理父子关系,而且它所做的(过期关系)似乎需要为每个模型编写自定义代码。(2.1) 有没有办法使这更加灵活?(2.2) 是否可以配置SQLAlchemy的relationship()
返回给定外键的最大版本对象?