Hi,
what's the right way to detemine what changed on an object? I use
ext.declarative and mapper extension, which calls code in the end of message
after_insert and before_update. It skips M2M relations because .get_history()
call loads everything in memory.
Is there better way to determine what's going to be stored in database?
def modifications(obj):
'''Return dictionary of changes in object.
No modifications are visible after saving object.
Parameters:
obj - object itself
Output dictionary:
keys - object attributes which are changed
values - 2-tuple of changes in format (from, to)
'''
state = orm.attributes.instance_state(obj)
dict_ = state.dict
changes = {}
# copying fixes "RuntimeError: dictionary changed size during iteration"
for attr in list(state.manager.attributes):
if not hasattr(attr.impl, 'get_history'):
continue
# we don't want those because they can fetch a lot of objects in memory
# ONETOMANY == backreference to foreign key
if (isinstance(attr.property, orm.properties.RelationProperty) and
attr.property.direction in (ONETOMANY, MANYTOMANY)):
continue
key = attr.impl.key
try:
added, unchanged, deleted = attr.impl.get_history(state, dict_)
except ValueError, e:
changes[key] = {'error': str(e),
'descr': 'possibly backreference of m2m relation'}
else:
if added or deleted:
if deleted != added:
changes[key] = map(modeltorepr, deleted), map(modeltorepr,
added)
return changes
This works, but there is a problem - if attr is a backreference
--
Alexander
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.