]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add real .entities to _BundleEntity
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 19 Dec 2016 17:39:15 +0000 (12:39 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 19 Dec 2016 17:41:28 +0000 (12:41 -0500)
Fixed bug where the single-table inheritance query criteria would not
be inserted into the query in the case that the :class:`.Bundle`
construct were used as the selection criteria.

Change-Id: Ib7c128ceef5c3220a098cdfd0270c43a2a67716d
Fixes: #3874
doc/build/changelog/changelog_11.rst
lib/sqlalchemy/orm/query.py
test/orm/inheritance/test_single.py

index b68f4aa29e7e0bf0b36bb4cecd607a7215efa9f2..27417a67922b5f28947d15a6aab481c9a8da038e 100644 (file)
 .. changelog::
     :version: 1.1.5
 
+    .. change:: 3874
+        :tags: bug, orm
+        :tickets: 3874
+
+        Fixed bug where the single-table inheritance query criteria would not
+        be inserted into the query in the case that the :class:`.Bundle`
+        construct were used as the selection criteria.
+
     .. change:: pg_timestamp_zero_prec
         :tags: bug, postgresql
 
index 340e71d25e660ef6ed9965e667357b5bba0c029f..7703453157035e191031150058cc262e41fff997 100644 (file)
@@ -3802,10 +3802,15 @@ class _BundleEntity(_QueryEntity):
                 else:
                     _ColumnEntity(self, expr, namespace=self)
 
-        self.entities = ()
-
         self.supports_single_entity = self.bundle.single_entity
 
+    @property
+    def entities(self):
+        entities = []
+        for ent in self._entities:
+            entities.extend(ent.entities)
+        return entities
+
     @property
     def entity_zero(self):
         for ent in self._entities:
index d12d9697722890783d2d85a5277a88543ed718fd..5d3e4cf6773835f25b29c1217e7fa9e0d6b6a1ed 100644 (file)
@@ -51,12 +51,12 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
         mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
         mapper(JuniorEngineer, inherits=Engineer, polymorphic_identity='juniorengineer')
 
-    def test_single_inheritance(self):
-        Employee, JuniorEngineer, Manager, Engineer = (self.classes.Employee,
-                                self.classes.JuniorEngineer,
-                                self.classes.Manager,
-                                self.classes.Engineer)
-
+    def _fixture_one(self):
+        Employee, JuniorEngineer, Manager, Engineer = (
+            self.classes.Employee,
+            self.classes.JuniorEngineer,
+            self.classes.Manager,
+            self.classes.Engineer)
 
         session = create_session()
 
@@ -65,6 +65,16 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
         e2 = JuniorEngineer(name='Ed', engineer_info='oh that ed')
         session.add_all([m1, e1, e2])
         session.flush()
+        return session, m1, e1, e2
+
+    def test_single_inheritance(self):
+        Employee, JuniorEngineer, Manager, Engineer = (
+            self.classes.Employee,
+            self.classes.JuniorEngineer,
+            self.classes.Manager,
+            self.classes.Engineer)
+
+        session, m1, e1, e2 = self._fixture_one()
 
         assert session.query(Employee).all() == [m1, e1, e2]
         assert session.query(Engineer).all() == [e1, e2]
@@ -80,18 +90,12 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
         assert row.employee_id == e1.employee_id
 
     def test_multi_qualification(self):
-        JuniorEngineer, Manager, Engineer = (self.classes.JuniorEngineer,
-                                self.classes.Manager,
-                                self.classes.Engineer)
-
-        session = create_session()
-
-        m1 = Manager(name='Tom', manager_data='knows how to manage things')
-        e1 = Engineer(name='Kurt', engineer_info='knows how to hack')
-        e2 = JuniorEngineer(name='Ed', engineer_info='oh that ed')
+        JuniorEngineer, Manager, Engineer = (
+            self.classes.JuniorEngineer,
+            self.classes.Manager,
+            self.classes.Engineer)
 
-        session.add_all([m1, e1, e2])
-        session.flush()
+        session, m1, e1, e2 = self._fixture_one()
 
         ealias = aliased(Engineer)
         eq_(
@@ -130,6 +134,88 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
         #    []
         # )
 
+    def test_column_qualification(self):
+        Employee, JuniorEngineer, Manager, Engineer = (
+            self.classes.Employee,
+            self.classes.JuniorEngineer,
+            self.classes.Manager,
+            self.classes.Engineer)
+
+        session, m1, e1, e2 = self._fixture_one()
+
+        m1id, e1id, e2id = m1.employee_id, e1.employee_id, e2.employee_id
+
+        def scalar(q):
+            return [x for x, in q]
+
+        eq_(
+            scalar(session.query(Employee.employee_id)),
+            [m1id, e1id, e2id]
+        )
+
+        eq_(
+            scalar(session.query(Engineer.employee_id)),
+            [e1id, e2id]
+        )
+
+        eq_(
+            scalar(session.query(Manager.employee_id)), [m1id]
+        )
+
+        # this currently emits "WHERE type IN (?, ?) AND type IN (?, ?)",
+        # so no result.
+        eq_(
+            session.query(Manager.employee_id, Engineer.employee_id).all(),
+            []
+        )
+
+        eq_(
+            scalar(session.query(JuniorEngineer.employee_id)),
+            [e2id]
+        )
+
+    def test_bundle_qualification(self):
+        Employee, JuniorEngineer, Manager, Engineer = (
+            self.classes.Employee,
+            self.classes.JuniorEngineer,
+            self.classes.Manager,
+            self.classes.Engineer)
+
+        session, m1, e1, e2 = self._fixture_one()
+
+        m1id, e1id, e2id = m1.employee_id, e1.employee_id, e2.employee_id
+
+        def scalar(q):
+            return [x[0] for x, in q]
+
+        eq_(
+            scalar(session.query(Bundle("name", Employee.employee_id))),
+            [m1id, e1id, e2id]
+        )
+
+        eq_(
+            scalar(session.query(Bundle("name", Engineer.employee_id))),
+            [e1id, e2id]
+        )
+
+        eq_(
+            scalar(session.query(Bundle("name", Manager.employee_id))), [m1id]
+        )
+
+        # this currently emits "WHERE type IN (?, ?) AND type IN (?, ?)",
+        # so no result.
+        eq_(
+            session.query(
+                Bundle("name", Manager.employee_id, Engineer.employee_id)
+            ).all(),
+            []
+        )
+
+        eq_(
+            scalar(session.query(Bundle("name", JuniorEngineer.employee_id))),
+            [e2id]
+        )
+
     def test_from_self(self):
         Engineer = self.classes.Engineer