【问题标题】:How can I get a SQLAlchemy ORM object's previous state after a db update?如何在数据库更新后获取 SQLAlchemy ORM 对象的先前状态?
【发布时间】:2013-03-16 13:21:06
【问题描述】:

问题是我不知道如何使用 SQLAlchemy 在对象进入新状态时通知我。

我正在使用 SQLAlchemy ORM(声明式)来更新对象:

class Customer(declarative_base()):

    __table_name__ = "customer"

    id = Column(Integer, primary_key=True)
    status = Column(String)

我想知道对象何时进入状态。特别是在发布 UPDATE 和状态更改后。例如。 Customer.status == 'registered' 之前的状态不同。

我目前正在使用'set' 属性事件来执行此操作:

from sqlalchemy import event
from model import Customer

def on_set_attribute(target, value, oldvalue, initiator):
    print target.status
    print value
    print oldvalue

event.listen(
        Customer.status,
        'set',
        on_set_attribute,
        propagate=True,
        active_history=True)

每次在该属性上调用“set”时,我的代码都会触发,我检查valueoldvalue 是否不同。问题是target 参数没有完全形成,所以它还没有填充所有的属性值。

有没有更好的方法来做到这一点?谢谢!

【问题讨论】:

    标签: python orm sqlalchemy crud


    【解决方案1】:

    我的解决方案是使用“after_flush”SessionEvent 而不是“set”AttributeEvent。

    非常感谢agronholm,他提供了专门检查对象值和旧值的示例 SessionEvent 代码。

    下面的解决方案是修改他的代码:

    def get_old_value(attribute_state):
        history = attribute_state.history
        return history.deleted[0] if history.deleted else None
    
    
    def trigger_attribute_change_events(object_):
        for mapper_property in object_mapper(object_).iterate_properties:
            if isinstance(mapper_property, ColumnProperty):
                key = mapper_property.key
                attribute_state = inspect(object_).attrs.get(key)
                history = attribute_state.history
    
                if history.has_changes():
                    value = attribute_state.value
                    # old_value is None for new objects and old value for dirty objects
                    old_value = get_old_value(attribute_state)
                    handler = registry.get(mapper_property)
                    if handler:
                        handler(object_, value, old_value)
    
    
    def on_after_flush(session, flush_context):
        changed_objects = session.new.union(session.dirty)
        for o in changed_objects:
            trigger_attribute_change_events(o)
    
    event.listen(session, "after_flush", on_after_flush)
    

    registry 是一个字典,其键是 MapperProperty 的,其值是事件处理程序。 sessioneventinspectobject_mapper 都是 sqlalchemy 类和函数。

    【讨论】:

      【解决方案2】:

      使用before_update 事件或before_flush 事件在稍后的时间点拦截发生的这种情况。

      【讨论】:

        猜你喜欢
        • 2022-01-15
        • 1970-01-01
        • 2019-07-18
        • 2018-11-24
        • 1970-01-01
        • 2014-06-02
        • 2018-07-19
        • 2015-02-15
        • 2010-09-21
        相关资源
        最近更新 更多