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(*),
"""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
["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)" % (
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()