I want to log every action what will be done with some SQLAlchemy-Models.
So, I have a after_insert, after_delete and before_update hooks, where I will save previous and current representation of model,
def keep_logs(cls): @event.listens_for(cls, 'after_delete') def after_delete_trigger(mapper, connection, target): pass @event.listens_for(cls, 'after_insert') def after_insert_trigger(mapper, connection, target): pass @event.listens_for(cls, 'before_update') def before_update_trigger(mapper, connection, target): prev = cls.query.filter_by(id=target.id).one() # comparing previous and current model MODELS_TO_LOGGING = ( User, ) for cls in MODELS_TO_LOGGING: keep_logs(cls)
But there is one problem: when I'm trying to find model in before_update hook, SQLA returns modified (dirty) version. How can I get previous version of model before updating it? Is there a different way to keep model changes?
Thanks!
SQLAlchemy tracks the changes to each attribute. You don't need to (and shouldn't) query the instance again in the event. Additionally, the event is triggered for any instance that has been modified, even if that modification will not change any data. Loop over each column, checking if it has been modified, and store any new values.
@event.listens_for(cls, 'before_update') def before_update(mapper, connection, target): state = db.inspect(target) changes = {} for attr in state.attrs: hist = attr.load_history() if not hist.has_changes(): continue # hist.deleted holds old value # hist.added holds new value changes[attr.key] = hist.added # now changes map keys to new values
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With