From: Mike Bayer Date: Wed, 11 Aug 2010 15:57:56 +0000 (-0400) Subject: - a warning is emitted in mapper() if the polymorphic_on X-Git-Tag: rel_0_6_4~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=169263439f2de532bd0783ba0210796835a936a7;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - a warning is emitted in mapper() if the polymorphic_on column is not present either in direct or derived form in the mapped selectable or in the with_polymorphic selectable, instead of silently ignoring it. Look for this to become an exception in 0.7. --- diff --git a/CHANGES b/CHANGES index b1f3af2e1b..24bd97b288 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,13 @@ CHANGES ConcurrentModificationError in an "except:" clause. + - a warning is emitted in mapper() if the polymorphic_on + column is not present either in direct or derived + form in the mapped selectable or in the + with_polymorphic selectable, instead of silently + ignoring it. Look for this to become an + exception in 0.7. + - Moving an o2m object from one collection to another, or vice versa changing the referenced object by an m2o, where the foreign key is also a diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 74853dbbae..e57331fa50 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -574,6 +574,13 @@ class Mapper(object): if col is None: instrument = False col = self.polymorphic_on + if self.with_polymorphic is None \ + or self.with_polymorphic[1].corresponding_column(col) \ + is None: + util.warn("Could not map polymoprhic_on column " + "'%s' to the mapped table - polymorphic " + "loads will not function properly" + % col.description) else: instrument = True if self._should_exclude(col.key, col.key, local=False): diff --git a/test/orm/inheritance/test_basic.py b/test/orm/inheritance/test_basic.py index 7607bd0829..4c6247fa85 100644 --- a/test/orm/inheritance/test_basic.py +++ b/test/orm/inheritance/test_basic.py @@ -16,7 +16,8 @@ class O2MTest(_base.MappedTest): def define_tables(cls, metadata): global foo, bar, blub foo = Table('foo', metadata, - Column('id', Integer, primary_key=True, test_needs_autoincrement=True), + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), Column('data', String(20))) bar = Table('bar', metadata, @@ -60,14 +61,73 @@ class O2MTest(_base.MappedTest): b1.parent_foo = f b2.parent_foo = f sess.flush() - compare = ','.join([repr(b1), repr(b2), repr(b1.parent_foo), repr(b2.parent_foo)]) + compare = ','.join([repr(b1), repr(b2), repr(b1.parent_foo), + repr(b2.parent_foo)]) sess.expunge_all() l = sess.query(Blub).all() - result = ','.join([repr(l[0]), repr(l[1]), repr(l[0].parent_foo), repr(l[1].parent_foo)]) + result = ','.join([repr(l[0]), repr(l[1]), + repr(l[0].parent_foo), repr(l[1].parent_foo)]) print compare print result self.assert_(compare == result) - self.assert_(l[0].parent_foo.data == 'foo #1' and l[1].parent_foo.data == 'foo #1') + self.assert_(l[0].parent_foo.data == 'foo #1' + and l[1].parent_foo.data == 'foo #1') + +class PolymorphicOnNotLocalTest(_base.MappedTest): + @classmethod + def define_tables(cls, metadata): + t1 = Table('t1', metadata, + Column('id', Integer, primary_key=True), + Column('x', String(10)), + Column('q', String(10))) + t2 = Table('t2', metadata, + Column('id', Integer, primary_key=True), + Column('y', String(10)), + Column('xid', ForeignKey('t1.x'))) + + @testing.resolve_artifact_names + def test_bad_polymorphic_on(self): + class InterfaceBase(object): + pass + + t1t2_join = select([t1.c.x], from_obj=[t1.join(t2)]).alias() + def go(): + interface_m = mapper(InterfaceBase, t2, + polymorphic_on=t1t2_join.c.x, + polymorphic_identity=0) + + assert_raises_message( + sa_exc.SAWarning, + "Could not map polymoprhic_on column 'x' to the mapped table - " + "polymorphic loads will not function properly", + go + ) + clear_mappers() + + # if its in the with_polymorphic, then its OK + interface_m = mapper(InterfaceBase, t2, + polymorphic_on=t1t2_join.c.x, + with_polymorphic=('*', t1t2_join), + polymorphic_identity=0) + compile_mappers() + + clear_mappers() + + # if with_polymorphic, but its not present, not OK + def go(): + t1t2_join_2 = select([t1.c.q], from_obj=[t1.join(t2)]).alias() + interface_m = mapper(InterfaceBase, t2, + polymorphic_on=t1t2_join.c.x, + with_polymorphic=('*', t1t2_join_2), + polymorphic_identity=0) + assert_raises_message( + sa_exc.SAWarning, + "Could not map polymoprhic_on column 'x' to the mapped table - " + "polymorphic loads will not function properly", + go + ) + + class FalseDiscriminatorTest(_base.MappedTest): @classmethod