]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Allow None to cancel Query.group_by()
authorIuri Diniz <iuridiniz@gmail.com>
Fri, 29 Jul 2016 16:54:22 +0000 (12:54 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 29 Jul 2016 22:44:34 +0000 (18:44 -0400)
This replicates the same behavior as order_by().

order_by() will also be updated to deprecate passing
of False as this is no longer functionally different
than passing None.

Change-Id: I2fc05d0317d28b6c83373769a48f7eea32d56290
Pull-request: https://github.com/zzzeek/sqlalchemy/pull/297

doc/build/changelog/changelog_11.rst
lib/sqlalchemy/orm/query.py
test/orm/test_query.py

index b6129cf77616346a92d97eb0a4476515581be391..9a65e66a29094ab1e741fb48e3cc71e6f1fc1bcf 100644 (file)
 .. changelog::
     :version: 1.1.0
 
+    .. change::
+        :tags: feature, orm
+
+        The :meth:`.Query.group_by` method now resets the group by collection
+        if an argument of ``None`` is passed, in the same way that
+        :meth:`.Query.order_by` has worked for a long time.  Pull request
+        courtesy Iuri Diniz.
+
 .. changelog::
     :version: 1.1.0b3
     :released: July 26, 2016
index c1daaaf075254c1fdc7dfba318da419051bf54f9..c5ecbaffe771d11b3f21d3266abf2351baca518c 100644 (file)
@@ -1549,7 +1549,21 @@ class Query(object):
     @_generative(_no_statement_condition, _no_limit_offset)
     def group_by(self, *criterion):
         """apply one or more GROUP BY criterion to the query and return
-        the newly resulting :class:`.Query`"""
+        the newly resulting :class:`.Query`
+
+        All existing GROUP BY settings can be suppressed by
+        passing ``None`` - this will suppress any GROUP BY configured
+        on mappers as well.
+
+        .. versionadded:: 1.1 GROUP BY can be cancelled by passing None,
+           in the same way as ORDER BY.
+
+        """
+
+        if len(criterion) == 1:
+            if criterion[0] is None:
+                self._group_by = False
+                return
 
         criterion = list(chain(*[_orm_columns(c) for c in criterion]))
         criterion = self._adapt_col_list(criterion)
index 34343d78d072b538d4c5be3400d872e615921417..86be1879ef4f6b6f9e37ae981fa0051ec5131843 100644 (file)
@@ -1574,6 +1574,57 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
                     User(id=7, name='jack'),
                     Address(email_address='jack@bean.com', user_id=7, id=1))])
 
+    def test_group_by_plain(self):
+        User = self.classes.User
+        s = create_session()
+
+        q1 = s.query(User.id, User.name).group_by(User.name)
+        self.assert_compile(
+            select([q1]),
+            "SELECT users_id, users_name FROM (SELECT users.id AS users_id, "
+            "users.name AS users_name FROM users GROUP BY users.name)"
+        )
+
+    def test_group_by_append(self):
+        User = self.classes.User
+        s = create_session()
+
+        q1 = s.query(User.id, User.name).group_by(User.name)
+
+        # test append something to group_by
+        self.assert_compile(
+            select([q1.group_by(User.id)]),
+            "SELECT users_id, users_name FROM (SELECT users.id AS users_id, "
+            "users.name AS users_name FROM users GROUP BY users.name, users.id)"
+        )
+
+    def test_group_by_cancellation(self):
+        User = self.classes.User
+        s = create_session()
+
+        q1 = s.query(User.id, User.name).group_by(User.name)
+        # test cancellation by using None, replacement with something else
+        self.assert_compile(
+            select([q1.group_by(None).group_by(User.id)]),
+            "SELECT users_id, users_name FROM (SELECT users.id AS users_id, "
+            "users.name AS users_name FROM users GROUP BY users.id)"
+        )
+
+        # test cancellation by using None, replacement with nothing
+        self.assert_compile(
+            select([q1.group_by(None)]),
+            "SELECT users_id, users_name FROM (SELECT users.id AS users_id, "
+            "users.name AS users_name FROM users)"
+        )
+
+    def test_group_by_cancelled_still_present(self):
+        User = self.classes.User
+        s = create_session()
+
+        q1 = s.query(User.id, User.name).group_by(User.name).group_by(None)
+
+        q1._no_criterion_assertion("foo")
+
 
 class ColumnPropertyTest(_fixtures.FixtureTest, AssertsCompiledSQL):
     __dialect__ = 'default'