问题是我无法弄清楚当对象进入新状态时如何使用sqlAlchemy通知我.
我正在使用sqlAlchemy ORM(声明性)来更新对象:
class Customer(declarative_base()):
__table_name__ = "customer"
id = Column(Integer,primary_key=True)
status = Column(String)
我想知道一个物体进入状态的时间.特别是在发布UPDATE并且状态发生变化之后.例如. Customer.status ==’已注册’,之前有不同的状态.
我目前正在使用’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’时,我的代码都会触发,我检查值和oldvalue是否不同.问题是目标参数没有完全形成,因此它还没有填充所有属性值.
有一个更好的方法吗?谢谢!
最佳答案
我的解决方案是使用’after_flush’SessionEvent而不是’set’BeanntEvent.
非常感谢agronholm提供了专门检查对象值和oldvalue的示例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_,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)
注册表是一个字典,其键是MapperProperty,其值是事件处理程序.
session,event,inspect和object_mapper都是sqlalchemy类和函数.