]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
don't create a history entry when an object in a backref has changed
authorMatt Chisholm <matt@theory.org>
Sat, 15 Jun 2013 16:15:29 +0000 (18:15 +0200)
committerMatt Chisholm <matt@theory.org>
Sat, 15 Jun 2013 16:15:29 +0000 (18:15 +0200)
The code that determines whether an object in a relation has been added/removed does not take into account that that relation may be a backref. If the relation is a backref, then nothing on the current table is changing, and therefore no history entry should be created.

examples/versioning/history_meta.py
examples/versioning/test_versioning.py

index 45f1c8369905bc3c73577d2228f2d6f782fac861..deef67a0a66fc469c8fa15dbc145d9bf73919a1d 100644 (file)
@@ -158,8 +158,12 @@ def create_version(obj, session, deleted = False):
         for prop in obj_mapper.iterate_properties:
             if isinstance(prop, RelationshipProperty) and \
                 attributes.get_history(obj, prop.key).has_changes():
-                obj_changed = True
-                break
+                for p in prop.local_columns:
+                    if p.foreign_keys:
+                        obj_changed = True
+                        break
+                if obj_changed is True:
+                    break
 
     if not obj_changed and not deleted:
         return
index 5b57ecaa209c06c64909c9444dfd283cfaff67d3..2bc18df635aa3c7669bafedb31eb97b564594fb3 100644 (file)
@@ -306,7 +306,7 @@ class TestVersioning(TestCase):
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
             related_id = Column(Integer, ForeignKey('somerelated.id'))
-            related = relationship("SomeRelated")
+            related = relationship("SomeRelated", backref='classes')
 
         SomeClassHistory = SomeClass.__history_mapper__.class_
 
@@ -341,3 +341,38 @@ class TestVersioning(TestCase):
 
         assert sc.version == 3
 
+    def test_backref_relationship(self):
+
+        class SomeRelated(Base, ComparableEntity):
+            __tablename__ = 'somerelated'
+
+            id = Column(Integer, primary_key=True)
+            name = Column(String(50))
+            related_id = Column(Integer, ForeignKey('sometable.id'))
+            related = relationship("SomeClass", backref='related')
+
+        class SomeClass(Versioned, Base, ComparableEntity):
+            __tablename__ = 'sometable'
+
+            id = Column(Integer, primary_key=True)
+
+        self.create_tables()
+        sess = Session()
+        sc = SomeClass()
+        sess.add(sc)
+        sess.commit()
+
+        assert sc.version == 1
+
+        sr = SomeRelated(name='sr', related=sc)
+        sess.add(sr)
+        sess.commit()
+
+        assert sc.version == 1
+
+        sr.name = 'sr2'
+        sess.commit()
+
+        assert sc.version == 1
+        sess.delete(sr)
+        sess.commit()