13

我想在仅附加的数据存储中重新实现我现有的一些 SQLAlchemy 模型;仅附加意味着对象仅使用 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.         

此外,

我知道如何解决大多数这些问题,但我正在努力处理 SQLAlchemy 中的事件挂钩,这些挂钩将处理某些需要在更新和删除时完成的事情。

SQLAlchemy 文档已经有一些基本的版本控制示例。版本化的示例接近我想要的,但它们不处理 (1) 删除和 (2) 外键关系。

(1) 删除。我知道有一个session.deleted字段,我会以与versioned_rows.pysession.dirty示例中的迭代方式类似的方式对其进行迭代——但我如何从待删除列表中取消标记该项目并创建一个新项目?

(2) 上面的例子只处理了一个父子关系,它的处理方式(使关系过期)似乎需要为每个模型自定义代码。(2.1) 有没有办法让它更灵活?(2.2) 是否可以将 SQLAlchemy 配置relationship()为返回给定外键的 max(version) 对象?

4

2 回答 2

2

与 ORM 工具无关的一件有用的事情可能是“代替”触发器。例如,您可以捕获更新前事件,并使用新更新的数据打开一个增量版本号。

对于 postgresql,它们在此处进行了详细说明

当然,您必须更改模型(在 PK 等上)。

此外,值得研究性能影响,因为您可能必须进行递归查询才能获取“最新版本”(通过视图层或在 sql alchemy where 子句/等中)

于 2014-11-24T18:21:25.223 回答
0

您可能听起来很疯狂,但实际上使用不同类型的数据库可能会更好。你知道Datomic 吗?. 传统 RDBMS 与此类系统之间的根本区别之一是没有就地更新,这是 RDBMS 更新磁盘上文件的方式。相反,所有内容都是版本化的,您可以针对每个资源的每次更改返回所有以前的数据库版本。此外,您只需将感兴趣的时间作为参数传递,即可轻松查看整个数据库在特定时刻的状态。还有很多其他有趣的优点,我强烈建议看看 Rich Hickey 的一些关于它的演讲,例如这个. 这绝对是您当前尝试的一种根本不同的方法,但是必须考虑是否会在每一步都与工具作斗争,以一种他们真正没有的方式使用它们设计(RDBMS,ORM,迁移管理器,...)。相反,您可以将这种复杂性降低一层,让不同类型的数据库为您处理它。

于 2015-04-19T08:23:47.227 回答