Hello, The version recipe on the wiki will version if the object is dirty, but I thought it would be more useful if it did it only when there was an actual change.
The diff is below, added a test too, and I would be happy to upload it after someone looks over it? The recipe is at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/LogVersions Thanks David --- a/history_meta_old.py +++ b/history_meta.py @@ -96,7 +96,7 @@ def versioned_objects(iter): if hasattr(obj, '__history_mapper__'): yield obj -def create_version(obj, session): +def create_version(obj, session, deleted = False): obj_mapper = object_mapper(obj) history_mapper = obj.__history_mapper__ history_cls = history_mapper.class_ @@ -104,6 +104,8 @@ def create_version(obj, session): obj_state = attributes.instance_state(obj) attr = {} + + obj_changed = False for om, hm in zip(obj_mapper.iterate_to_root(), history_mapper.iterate_to_root()): if hm.single: @@ -137,11 +139,15 @@ def create_version(obj, session): if d: attr[hist_col.key] = d[0] + obj_changed = True elif u: attr[hist_col.key] = u[0] else: raise Exception("TODO: what makes us arrive here ?") + if not obj_changed and not deleted: + return + attr['version'] = obj.version hist = history_cls() for key, value in attr.iteritems(): @@ -151,6 +157,8 @@ def create_version(obj, session): class VersionedListener(SessionExtension): def before_flush(self, session, flush_context, instances): - for obj in versioned_objects(session.dirty.union (session.deleted)): + for obj in versioned_objects(session.dirty): create_version(obj, session) + for obj in versioned_objects(session.deleted): + create_version(obj, session, deleted = True) --- a/test_versioning_old.py +++ b/test_versioning.py @@ -1,5 +1,5 @@ from sqlalchemy.ext.declarative import declarative_base -from history.history_meta import VersionedMeta, VersionedListener +from history_meta import VersionedMeta, VersionedListener from sqlalchemy import create_engine, Column, Integer, String, ForeignKey from sqlalchemy.orm import clear_mappers, compile_mappers, sessionmaker, deferred from testlib import eq_, Comparable @@ -59,6 +59,19 @@ class TestVersioning(object): assert sc.version == 3 sess.commit() + + sc.name = 'temp' + sc.name = 'sc1modified2' + + sess.commit() + + eq_( + sess.query(SomeClassHistory).order_by (SomeClassHistory.version).all(), + [ + SomeClassHistory(version=1, name='sc1'), + SomeClassHistory(version=2, name='sc1modified') + ] + ) sess.delete(sc) sess.commit() @@ -72,6 +85,9 @@ class TestVersioning(object): ] ) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---