]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added add_columns() to Query - pending deprecates add_column()
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 23 Mar 2010 22:53:42 +0000 (18:53 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 23 Mar 2010 22:53:42 +0000 (18:53 -0400)
- refined subquery strategy to use more public Query API

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

diff --git a/CHANGES b/CHANGES
index 4640408e384b47448df1b741cce0514b56f6a92d..64bb290c2a2992b9529d4fe48dd8ddac3b662134 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -23,7 +23,11 @@ CHANGES
     load such as query(A).options(eagerload(A.b, B.c))
     wouldn't eagerload anything, but using eagerload("b.c") would
     work fine.
-     
+
+  - Query gains an add_columns(*columns) method which is a multi-
+    version of add_column(col).  add_column(col) is future 
+    deprecated.
+    
 0.6beta2
 ========
 
index 2dfefc43326eafcb68ad6452b02a783c3e5dc66f..5e7a2028e67f5e1224b40ed191a67145e1828e84 100644 (file)
@@ -662,16 +662,25 @@ class Query(object):
             return None
 
     @_generative()
-    def add_column(self, column):
-        """Add a SQL ColumnElement to the list of result columns to be returned."""
+    def add_columns(self, *column):
+        """Add one or more column expressions to the list 
+        of result columns to be returned."""
 
         self._entities = list(self._entities)
         l = len(self._entities)
-        _ColumnEntity(self, column)
+        for c in column:
+            _ColumnEntity(self, c)
         # _ColumnEntity may add many entities if the
         # given arg is a FROM clause
         self._setup_aliasizers(self._entities[l:])
 
+    @util.pending_deprecation("add_column() superceded by add_columns()")
+    def add_column(self, column):
+        """Add a column expression to the list of result columns
+        to be returned."""
+        
+        return self.add_columns(column)
+
     def options(self, *args):
         """Return a new Query object, applying the given list of
         MapperOptions.
index 4431b408fc59fc506d11804e92cb80cc4e50d160..b6ca1090d7ec4765c1ce1febbd695163143982b9 100644 (file)
@@ -707,44 +707,38 @@ class SubqueryLoader(AbstractRelationshipLoader):
         
         q._attributes[('subquery_path', None)] = subq_path
 
-        # now select from it as a subquery.
-        local_attr = [
-            self.parent._get_col_to_prop(c).class_attribute
-            for c in local_cols
-        ]
-
         q = q.from_self(self.mapper)
         q._entities[0].disable_aliasing = True
 
-        to_join = [(subq_path[i], subq_path[i+1]) 
-                            for i in xrange(0, len(subq_path), 2)]
-        
-        for i, (mapper, key) in enumerate(to_join):
-            alias_join = i < len(to_join) - 1
-            second_to_last = i == len(to_join) - 2
-            
-            prop = mapper.get_property(key)
-            q = q.join(prop.class_attribute, aliased=alias_join)
-            
-            if alias_join and second_to_last:
-                cols = [
-                    q._adapt_clause(col, True, False)
-                    for col in local_cols
+        to_join = [
+                    (subq_path[i], subq_path[i+1]) 
+                    for i in xrange(0, len(subq_path), 2)
                 ]
-                for col in cols:
-                    q = q.add_column(col)
-                q = q.order_by(*cols)
-        
+
         if len(to_join) < 2:
             local_attr = [
                 self.parent._get_col_to_prop(c).class_attribute
                 for c in local_cols
             ]
-
-            for col in local_attr:
-                q = q.add_column(col)
-            q = q.order_by(*local_attr)
-                
+        else:
+            parent_alias = mapperutil.AliasedClass(self.parent)
+            local_attr = [
+                getattr(parent_alias, self.parent._get_col_to_prop(c).key)
+                for c in local_cols
+            ]
+        q = q.add_columns(*local_attr)
+        q = q.order_by(*local_attr)
+            
+        for i, (mapper, key) in enumerate(to_join):
+            alias_join = i < len(to_join) - 1
+            second_to_last = i == len(to_join) - 2
+            
+            prop = mapper.get_property(key)
+            
+            if second_to_last:
+                q = q.join((parent_alias, prop.class_attribute))
+            else:
+                q = q.join(prop.class_attribute, aliased=alias_join)
 
         # propagate loader options etc. to the new query
         q = q._with_current_path(subq_path)
index 83297e165d2500b574ec13256fda857d23ff2559..f7eb5d5e40be6c291a7a9403980f38989013d3fe 100644 (file)
@@ -195,7 +195,8 @@ def _produce_test(select_type):
             sess = create_session()
 
             # assert the JOINs dont over JOIN
-            assert sess.query(Person).with_polymorphic('*').options(eagerload(Engineer.machines)).limit(2).offset(1).with_labels().subquery().count().scalar() == 2
+            assert sess.query(Person).with_polymorphic('*').options(eagerload(Engineer.machines)).\
+                                    limit(2).offset(1).with_labels().subquery().count().scalar() == 2
 
             def go():
                 eq_(sess.query(Person).with_polymorphic('*').options(eagerload(Engineer.machines))[1:3], all_employees[1:3])