summaryrefslogtreecommitdiff
path: root/test/ext/declarative
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-02-11 19:55:34 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-02-11 19:55:34 -0500
commit4a79bc578c67297c707a00d8fafaba533e2833d9 (patch)
tree808a412724a8137a95472ba974def1073ea1a301 /test/ext/declarative
parent0050a8d3db04767b97e48f3aa71381b786481231 (diff)
downloadsqlalchemy-4a79bc578c67297c707a00d8fafaba533e2833d9.tar.gz
- Fixed bug where :class:`.AbstractConcreteBase` would fail to be
fully usable within declarative relationship configuration, as its string classname would not be available in the registry of classnames at mapper configuration time. The class now explicitly adds itself to the class regsitry, and additionally both :class:`.AbstractConcreteBase` as well as :class:`.ConcreteBase` set themselves up *before* mappers are configured within the :func:`.configure_mappers` setup, using the new :meth:`.MapperEvents.before_configured` event. [ticket:2950] - Added new :meth:`.MapperEvents.before_configured` event which allows an event at the start of :func:`.configure_mappers`, as well as ``__declare_first__()`` hook within declarative to complement ``__declare_last__()``. - modified how after_configured is invoked; we just make a dispatch() not actually connected to any mapper. this makes it easier to also invoke before_configured correctly. - improved the ComparableEntity fixture to handle collections that are sets.
Diffstat (limited to 'test/ext/declarative')
-rw-r--r--test/ext/declarative/test_inheritance.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py
index 01bf3f3f6..22dd32e45 100644
--- a/test/ext/declarative/test_inheritance.py
+++ b/test/ext/declarative/test_inheritance.py
@@ -1201,3 +1201,81 @@ class ConcreteInhTest(_RemoveListeners, DeclarativeTestBase):
__mapper_args__ = {'polymorphic_identity': "engineer",
'concrete': True}
self._roundtrip(Employee, Manager, Engineer, Boss, explicit_type=True)
+
+class ConcreteExtensionConfigTest(_RemoveListeners, testing.AssertsCompiledSQL, DeclarativeTestBase):
+ __dialect__ = 'default'
+
+ def test_classreg_setup(self):
+ class A(Base, fixtures.ComparableEntity):
+ __tablename__ = 'a'
+ id = Column(Integer, primary_key=True, test_needs_autoincrement=True)
+ data = Column(String(50))
+ collection = relationship("BC", primaryjoin="BC.a_id == A.id",
+ collection_class=set)
+
+ class BC(AbstractConcreteBase, Base, fixtures.ComparableEntity):
+ pass
+
+ class B(BC):
+ __tablename__ = 'b'
+ id = Column(Integer, primary_key=True, test_needs_autoincrement=True)
+
+ a_id = Column(Integer, ForeignKey('a.id'))
+ data = Column(String(50))
+ b_data = Column(String(50))
+ __mapper_args__ = {
+ "polymorphic_identity": "b",
+ "concrete": True
+ }
+
+ class C(BC):
+ __tablename__ = 'c'
+ id = Column(Integer, primary_key=True, test_needs_autoincrement=True)
+ a_id = Column(Integer, ForeignKey('a.id'))
+ data = Column(String(50))
+ c_data = Column(String(50))
+ __mapper_args__ = {
+ "polymorphic_identity": "c",
+ "concrete": True
+ }
+
+ Base.metadata.create_all()
+ sess = Session()
+ sess.add_all([
+ A(data='a1', collection=set([
+ B(data='a1b1', b_data='a1b1'),
+ C(data='a1b2', c_data='a1c1'),
+ B(data='a1b2', b_data='a1b2'),
+ C(data='a1c2', c_data='a1c2'),
+ ])),
+ A(data='a2', collection=set([
+ B(data='a2b1', b_data='a2b1'),
+ C(data='a2c1', c_data='a2c1'),
+ B(data='a2b2', b_data='a2b2'),
+ C(data='a2c2', c_data='a2c2'),
+ ]))
+ ])
+ sess.commit()
+ sess.expunge_all()
+
+ eq_(
+ sess.query(A).filter_by(data='a2').all(),
+ [
+ A(data='a2', collection=set([
+ B(data='a2b1', b_data='a2b1'),
+ B(data='a2b2', b_data='a2b2'),
+ C(data='a2c1', c_data='a2c1'),
+ C(data='a2c2', c_data='a2c2'),
+ ]))
+ ]
+ )
+
+ self.assert_compile(
+ sess.query(A).join(A.collection),
+ "SELECT a.id AS a_id, a.data AS a_data FROM a JOIN "
+ "(SELECT c.id AS id, c.a_id AS a_id, c.data AS data, "
+ "c.c_data AS c_data, CAST(NULL AS VARCHAR(50)) AS b_data, "
+ "'c' AS type FROM c UNION ALL SELECT b.id AS id, b.a_id AS a_id, "
+ "b.data AS data, CAST(NULL AS VARCHAR(50)) AS c_data, "
+ "b.b_data AS b_data, 'b' AS type FROM b) AS pjoin ON pjoin.a_id = a.id"
+ )