has no primary keys on the locally mapped table
(but has pks on the superclass table). [ticket:2019]
+ - Fixed bug where "middle" class in a polymorphic hierarchy
+ would have no 'polymorphic_on' column if it didn't also
+ specify a 'polymorphic_identity', leading to strange
+ errors upon refresh, wrong class loaded when querying
+ from that target. [ticket:2038]
+
- sql
- Column.copy(), as used in table.tometadata(), copies the
'doc' attribute. [ticket:2028]
if self.polymorphic_identity is not None:
self.polymorphic_map[self.polymorphic_identity] = self
- if self.polymorphic_on is None:
- for mapper in self.iterate_to_root():
- # try to set up polymorphic on using
- # correesponding_column(); else leave
- # as None
- if mapper.polymorphic_on is not None:
- self.polymorphic_on = \
- self.mapped_table.corresponding_column(
- mapper.polymorphic_on)
- break
+
+ if self.polymorphic_on is None:
+ for mapper in self.iterate_to_root():
+ # try to set up polymorphic on using
+ # correesponding_column(); else leave
+ # as None
+ if mapper.polymorphic_on is not None:
+ self.polymorphic_on = \
+ self.mapped_table.corresponding_column(
+ mapper.polymorphic_on)
+ break
else:
self._all_tables = set()
self.base_mapper = self
primary_language = Column(String(50))
assert 'inherits' not in Person.__mapper_args__
- assert class_mapper(Engineer).polymorphic_on is None
+ assert class_mapper(Engineer).polymorphic_identity is None
+ assert class_mapper(Engineer).polymorphic_on is Person.__table__.c.type
def test_custom_join_condition(self):
assert a.name=='a1new'
assert p.name=='p1new'
+class NoPolyIdentInMiddleTest(_base.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ Table('base', metadata,
+ Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
+ Column('type', String(50), nullable=False),
+ )
+
+ @classmethod
+ def setup_classes(cls):
+ class A(_base.BasicEntity):
+ pass
+ class B(A):
+ pass
+ class C(B):
+ pass
+
+ @classmethod
+ @testing.resolve_artifact_names
+ def setup_mappers(cls):
+ mapper(A, base, polymorphic_on=base.c.type)
+ mapper(B, inherits=A)
+ mapper(C, inherits=B, polymorphic_identity='c')
+
+ @testing.resolve_artifact_names
+ def test_load_from_middle(self):
+ s = Session()
+ s.add(C())
+ o = s.query(B).first()
+ eq_(o.type, 'c')
+ assert isinstance(o, C)
+
+ @testing.resolve_artifact_names
+ def test_load_from_base(self):
+ s = Session()
+ s.add(C())
+ o = s.query(A).first()
+ eq_(o.type, 'c')
+ assert isinstance(o, C)
+
+ @testing.resolve_artifact_names
+ def test_discriminator(self):
+ assert class_mapper(B).polymorphic_on is base.c.type
+ assert class_mapper(C).polymorphic_on is base.c.type
class DeleteOrphanTest(_base.MappedTest):
@classmethod