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
-~----------~----~----~----~------~----~------~--~---

Reply via email to