首页 > 解决方案 > 检查瞬态模型实例的“如果已修改”

问题描述

有没有办法在瞬态中添加一些历史或事件,所以当任何属性发生变化时,我们可以检测到它并将对象标记为已修改?

这样做的原因是我们在应用程序和数据库之间使用了redis。当我们创建/修改模型实例时,我们首先在 redis 中序列化这个对象(使用 pickle)。

此外,我们使用 celery 周期性任务从 redis 收集这些对象并将其填充到数据库中(这有助于我们最小化 UPDATE 操作)。

但问题是,当我们从 redis 反序列化模型实例时,状态是“瞬态的”,因此 sqlalchemy 会话将实例视为新对象,如果该对象被更改(通过检查等),我们没有任何信息。

我们在任务中通过添加附加列“revision”来解决这个问题,并在更新属性时手动执行 +=1。

我们在任务中的代码如下所示:

cached_instance = ... get deserialize models instances list

for inst in cached_instance:
  model = Model._decl_class_registry[inst.__tablename__]
  db_instance = session.query(model).filter(model.id==inst.id).one_or_none()
  if not db_instance:
    # new instance
    session.add(inst)
  else:
    if db_instance.revision < inst.revision:
        session.merge(inst)
session.commit()

但是该代码迫使我们使用额外的 SELECT 操作,这似乎没有效果。

验证器、hybrid_property、AttributeEvents 似乎也不是一个好的解决方案,因为我们有很多带有很多参数的模型......

任何想法?

标签: pythonsqlalchemy

解决方案


推荐阅读