]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug whereby the "unsaved, pending instance"
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 31 Jul 2008 16:41:41 +0000 (16:41 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 31 Jul 2008 16:41:41 +0000 (16:41 +0000)
FlushError raised for a pending orphan would not take
superclass mappers into account when generating
the list of relations responsible for the error.

CHANGES
lib/sqlalchemy/orm/session.py
test/orm/inheritance/basic.py

diff --git a/CHANGES b/CHANGES
index 4af45f143f8863a5bfcceeac87cc30f5640242ac..f1195e9ff1b930027f1f6acad852b967b0c0e2c0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -50,6 +50,11 @@ CHANGES
       should reduce the probability of "Attribute x was 
       not replaced during compile" warnings. (this generally
       applies to SQLA hackers, like Elixir devs).
+      
+    - Fixed bug whereby the "unsaved, pending instance" 
+      FlushError raised for a pending orphan would not take
+      superclass mappers into account when generating 
+      the list of relations responsible for the error.
 
 - sql
     - func.count() with no arguments renders as COUNT(*),
index 944fc9c5dd5a6c66d036fa7d1327477269ee6c99..6abe525fc5f56c55368a8b695a6fc0a6063fe619 100644 (file)
@@ -7,7 +7,7 @@
 """Provides the Session class and related utilities."""
 
 import weakref
-
+from itertools import chain
 import sqlalchemy.exceptions as sa_exc
 from sqlalchemy import util, sql, engine
 from sqlalchemy.sql import util as sql_util, expression
@@ -1385,7 +1385,7 @@ class Session(object):
                     ["any parent '%s' instance "
                      "via that classes' '%s' attribute" %
                      (cls.__name__, key)
-                     for (key, cls) in _state_mapper(state).delete_orphans])
+                     for (key, cls) in chain(*(m.delete_orphans for m in _state_mapper(state).iterate_to_root()))])
                 raise exc.FlushError(
                     "Instance %s is an unsaved, pending instance and is an "
                     "orphan (is not attached to %s)" % (
index 1f0cecbe41022d34b8147833f62dd3df9b2d4004..5028694fcfd0589d85a2f79d8bed89221dc48bdd 100644 (file)
@@ -873,6 +873,43 @@ class OverrideColKeyTest(ORMTest):
         sess.flush()
         assert sess.query(Sub).one().data == "im the data"
         
-
+class DeleteOrphanTest(ORMTest):
+    def define_tables(self, metadata):
+        global single, parent
+        single = Table('single', metadata,
+            Column('id', Integer, primary_key=True),
+            Column('type', String(50), nullable=False),
+            Column('data', String(50)),
+            Column('parent_id', Integer, ForeignKey('parent.id'), nullable=False),
+            )
+            
+        parent = Table('parent', metadata,
+                Column('id', Integer, primary_key=True),
+                Column('data', String(50))
+            )
+    
+    def test_orphan_message(self):
+        class Base(fixtures.Base):
+            pass
+        
+        class SubClass(Base):
+            pass
+        
+        class Parent(fixtures.Base):
+            pass
+        
+        mapper(Base, single, polymorphic_on=single.c.type, polymorphic_identity='base')
+        mapper(SubClass, inherits=Base, polymorphic_identity='sub')
+        mapper(Parent, parent, properties={
+            'related':relation(Base, cascade="all, delete-orphan")
+        })
+        
+        sess = create_session()
+        s1 = SubClass(data='s1')
+        sess.add(s1)
+        self.assertRaisesMessage(orm_exc.FlushError, 
+            "is not attached to any parent 'Parent' instance via that classes' 'related' attribute", sess.flush)
+        
+    
 if __name__ == "__main__":
     testenv.main()