【问题标题】:force object to be `dirty` in sqlalchemy在 sqlalchemy 中强制对象为“脏”
【发布时间】:2015-07-02 00:56:16
【问题描述】:

有没有办法强制将 sqlalchemy 映射的对象视为dirty?例如,给定 sqlalchemy 的 Object Relational Tutorial 的上下文,问题得到证明,

a=session.query(User).first()
a.__dict__['name']='eh'
session.dirty

屈服,

IdentitySet([])

我正在寻找一种方法来强制用户a 进入脏状态。

出现这个问题是因为使用 sqlalchemy 映射的类控制了属性 getter/setter 方法,这会阻止 sqlalchemy 注册更改。

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    我最近也遇到了同样的问题,但不是很明显。

    对象本身并不脏,但它们的属性是脏的。据我所知,SQLAlchemy 只会写回更改的属性,而不是整个对象。

    如果您使用set_attribute 设置属性并且它与原始属性数据不同,SQLAlchemy 会发现该对象是脏的(TODO:我需要详细说明它是如何进行比较的):

       from sqlalchemy.orm.attributes import set_attribute
       set_attribute(obj, data_field_name, data)
    

    如果你想将对象标记为脏而不考虑原始属性值,无论它是否改变了,使用flag_modified

       from sqlalchemy.orm.attributes import flag_modified
       flag_modified(obj, data_field_name)
    

    【讨论】:

    • 这个答案似乎有风险,但是,如果您将属性标记为已修改但 state_dict 中没有它的状态,则会导致 KeyError。 site-packages/sqlalchemy/orm/persistence.py”,第 454 行,在 _collect_update_commands value = state_dict[propkey]
    • 谢谢!是否可以使用 set 属性更改主键 ID?
    【解决方案2】:

    flag_modified 方法适用于知道该属性存在值的情况。 SQLAlchemy 文档states:

    将实例上的属性标记为“已修改”。

    这会在实例上设置“修改”标志并建立一个 给定属性的无条件更改事件。该属性必须 存在值,否则引发 InvalidRequestError。

    从 1.2 版开始,如果要标记整个实例,那么 flag_dirty 就是 solution

    将实例标记为“脏”而不提及任何特定属性。

    【讨论】:

      猜你喜欢
      • 2015-04-05
      • 2023-01-05
      • 1970-01-01
      • 2012-10-15
      • 2017-10-20
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多