From: Mike Bayer Date: Thu, 31 Jul 2008 16:41:41 +0000 (+0000) Subject: - Fixed bug whereby the "unsaved, pending instance" X-Git-Tag: rel_0_5beta3~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86126c98a26a6f07eb8cb9cc14fe71d8fca35aac;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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. --- diff --git a/CHANGES b/CHANGES index 4af45f143f..f1195e9ff1 100644 --- 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(*), diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 944fc9c5dd..6abe525fc5 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -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)" % ( diff --git a/test/orm/inheritance/basic.py b/test/orm/inheritance/basic.py index 1f0cecbe41..5028694fcf 100644 --- a/test/orm/inheritance/basic.py +++ b/test/orm/inheritance/basic.py @@ -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()