]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- query.select_from() also accepts mapped classes, aliased()
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Jan 2010 19:26:12 +0000 (19:26 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Jan 2010 19:26:12 +0000 (19:26 +0000)
    constructs, and mappers as arguments.  In particular this
    helps when querying from multiple joined-table classes to ensure
    the full join gets rendered.

CHANGES
lib/sqlalchemy/orm/query.py
test/orm/test_query.py

diff --git a/CHANGES b/CHANGES
index 2c1db03ccbe1b64112577c0bccda9f8642184065..895344dc4581773ffc031aba6d983ac1dc12d6c7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -129,6 +129,11 @@ CHANGES
     multiple comma separated entries within the FROM clause.
     Useful when selecting from multiple-homed join() clauses.
 
+  - query.select_from() also accepts mapped classes, aliased()
+    constructs, and mappers as arguments.  In particular this
+    helps when querying from multiple joined-table classes to ensure
+    the full join gets rendered.
+
   - query.get() can be used with a mapping to an outer join
     where one or more of the primary key values are None.
     [ticket:1135]
index 0a7a738c8d81df099d9163216f29c2eb85fd2ed2..d288e20c15e92c69ab2d683efd97973a9f5778a4 100644 (file)
@@ -1167,14 +1167,24 @@ class Query(object):
         """Set the `from_obj` parameter of the query and return the newly
         resulting ``Query``.  This replaces the table which this Query selects
         from with the given table.
+        
+        ``select_from()`` also accepts class arguments.   Though usually not necessary,
+        can ensure that the full selectable of the given mapper is applied, e.g.
+        for joined-table mappers.
 
         """
         
+        obj = []
         for fo in from_obj:
-            if not isinstance(fo, expression.FromClause):
+            if _is_mapped_class(fo):
+                mapper, selectable, is_aliased_class = _entity_info(fo)
+                obj.append(selectable)
+            elif not isinstance(fo, expression.FromClause):
                 raise sa_exc.ArgumentError("select_from() accepts FromClause objects only.")
+            else:
+                obj.append(fo)  
                 
-        self._set_select_from(*from_obj)
+        self._set_select_from(*obj)
 
     def __getitem__(self, item):
         if isinstance(item, slice):
index 22dd20209339089622d78f5465e66bd82f5274ca..c0835e74af46b3c642ad2d8cf106ebb7c9a67aa0 100644 (file)
@@ -1302,6 +1302,33 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
             , use_default_dialect = True
         )
 
+    @testing.resolve_artifact_names
+    def test_force_via_select_from(self):
+        sess = create_session()
+
+        self.assert_compile(
+            sess.query(Company).\
+                filter(Company.company_id==Engineer.company_id).\
+                filter(Engineer.primary_language=='java'),
+            "SELECT companies.company_id AS companies_company_id, companies.name AS companies_name "
+            "FROM companies, people, engineers "
+            "WHERE companies.company_id = people.company_id AND engineers.primary_language "
+            "= :primary_language_1",
+            use_default_dialect=True
+        )
+
+        self.assert_compile(
+            sess.query(Company).select_from(Company, Engineer).\
+                filter(Company.company_id==Engineer.company_id).\
+                filter(Engineer.primary_language=='java'),
+            "SELECT companies.company_id AS companies_company_id, companies.name AS companies_name "
+            "FROM companies, people JOIN engineers ON people.person_id = engineers.person_id "
+            "WHERE companies.company_id = people.company_id AND engineers.primary_language ="
+            " :primary_language_1",
+            use_default_dialect=True
+            
+        )
+            
     @testing.resolve_artifact_names
     def test_single_prop_of_type(self):
         sess = create_session()