inheritance attributes which were based on
column_property() or similar would fail to evaluate.
[ticket:1480]
+
+ - Improved support for MapperProperty objects overriding
+ that of an inherited mapper for non-concrete
+ inheritance setups - attribute extensions won't randomly
+ collide with each other. [ticket:1488]
+
+ - Added AttributeExtension to sqlalchemy.orm.__all__
- Improved error message when query() is called with
a non-SQL /entity expression. [ticket:1476]
return self
# initialize properties on all mappers
+ # note that _mapper_registry is unordered, which
+ # may randomly conceal/reveal issues related to
+ # the order of mapper compilation
for mapper in list(_mapper_registry):
if getattr(mapper, '_compile_failed', False):
raise sa_exc.InvalidRequestError("One or more mappers failed to compile. Exception was probably "
)
+class AttributeExtensionTest(_base.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ Table('t1',
+ metadata,
+ Column('id', Integer, primary_key=True),
+ Column('type', String(40)),
+ Column('data', String(50))
+
+ )
+
+ @testing.resolve_artifact_names
+ def test_cascading_extensions(self):
+ ext_msg = []
+
+ class Ex1(sa.orm.AttributeExtension):
+ def set(self, state, value, oldvalue, initiator):
+ ext_msg.append("Ex1 %r" % value)
+ return "ex1" + value
+
+ class Ex2(sa.orm.AttributeExtension):
+ def set(self, state, value, oldvalue, initiator):
+ ext_msg.append("Ex2 %r" % value)
+ return "ex2" + value
+
+ class A(_base.BasicEntity):
+ pass
+ class B(A):
+ pass
+ class C(B):
+ pass
+
+ mapper(A, t1, polymorphic_on=t1.c.type, polymorphic_identity='a', properties={
+ 'data':column_property(t1.c.data, extension=Ex1())
+ })
+ mapper(B, polymorphic_identity='b', inherits=A)
+ mc = mapper(C, polymorphic_identity='c', inherits=B, properties={
+ 'data':column_property(t1.c.data, extension=Ex2())
+ })
+
+ a1 = A(data='a1')
+ b1 = B(data='b1')
+ c1 = C(data='c1')
+
+ eq_(a1.data, 'ex1a1')
+ eq_(b1.data, 'ex1b1')
+ eq_(c1.data, 'ex2c1')
+
+ a1.data = 'a2'
+ b1.data='b2'
+ c1.data = 'c2'
+ eq_(a1.data, 'ex1a2')
+ eq_(b1.data, 'ex1b2')
+ eq_(c1.data, 'ex2c2')
+
+ eq_(ext_msg, ["Ex1 'a1'", "Ex1 'b1'", "Ex2 'c1'", "Ex1 'a2'", "Ex1 'b2'", "Ex2 'c2'"])
+
+
class MapperExtensionTest(_fixtures.FixtureTest):
run_inserts = None