这是我的方法:
def member_field_change_after_flush(session, flush_context):
"""
Keep track of MemberField objects changing per-session.
"""
member_fields = field_changes[session]
session_member_fields = filter(
lambda model: isinstance(model, MemberField),
session.new | session.dirty | session.deleted
)
for member_field in session_member_fields:
for mapper_property in object_mapper(member_field).iterate_properties:
if isinstance(mapper_property, ColumnProperty):
attribute_state = inspect(member_field).attrs.get(mapper_property.key)
history = attribute_state.history
if history.has_changes():
member_fields[member_field.field_id] = {
'member_id': member_field.member_id,
'old_value': history.deleted[0] if history.deleted else None,
'new_value': attribute_state.value,
'field_type': member_field.field.ref_field_type.column_key,
'account_id': member_field.account_id,
}
如果我将数据库中的值从100.2
改为100.2
,则SQLAlchemy
会认为某个值实际已更改并在history.deleted[0]
属性中记录dict
1}}上面。
我对Python很新,所以我不确定如何解决这个问题。
答案 0 :(得分:1)
每当更改某个值时,您的事件都会被触发。但是,要检查值是否实际更改,您需要调用session.is_modified(...)
。
示例:
for obj in session.dirty:
# Here, the field might have been set to the same value
if session.is_modified(obj):
# Here, the fields value has actually changed
我想以这种方式实现这一点的原因是优化。 docs say something similar:
is_modified(实例,include_collections = True,被动= True)
它实际上是在Session.dirty集合中检查给定实例的更昂贵和准确的版本;执行每个属性的净“脏”状态的完整测试。