]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Move enable_eagerloads(False) out of _from_self() into count()
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 16 Mar 2021 00:01:23 +0000 (20:01 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 16 Mar 2021 00:05:26 +0000 (20:05 -0400)
Fixed regression where calling upon :meth:`_orm.Query.count` in conjunction
with a loader option such as :func:`_orm.joinedload` would fail to ignore
the loader option. This is a behavior that has always been very specific to
the :meth:`_orm.Query.count` method; an error is normally raised if a given
:class:`_orm.Query` has options that don't apply to what it is returning.

Specifically, the call to enable_eagerloads(False) inside of
_from_self() is not needed as loader options are now not invoked
for subqueries.  Instead, set enable_eagerloads(False) in the
count() method itself, so that these options won't be considered
in this specific case.

Fixes: #6052
Change-Id: I0059ed3fb06156ef4116fd015cbef6f89808e8ef

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

index d685ac83ed6d809a1ead3999e5cedf08871fcd0f..4e2b4cdebbcff8e6878ef4e8958e76486c5cfa37 100644 (file)
@@ -1296,7 +1296,6 @@ class Query(
     def _from_self(self, *entities):
         fromclause = (
             self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
-            .enable_eagerloads(False)
             .correlate(None)
             .subquery()
             ._anonymous_fromclause()
@@ -3006,7 +3005,7 @@ class Query(
 
         """
         col = sql.func.count(sql.literal_column("*"))
-        return self._from_self(col).scalar()
+        return self._from_self(col).enable_eagerloads(False).scalar()
 
     def delete(self, synchronize_session="evaluate"):
         r"""Perform a DELETE with an arbitrary WHERE clause.
index c36946b6ed5ec3e3f48e044a9854d93907896266..05ab160074c9d1fc6ea1aa36c3e459aaa8b02b60 100644 (file)
@@ -3976,6 +3976,19 @@ class CountTest(QueryTest):
             2,
         )
 
+    def test_loader_options_ignored(self):
+        """test the count()-specific legacy behavior that loader
+        options are effectively ignored, as they previously were applied
+        before the count() function would be.
+
+        """
+
+        User = self.classes.User
+
+        s = fixture_session()
+
+        eq_(s.query(User).options(joinedload(User.addresses)).count(), 4)
+
     def test_count_char(self):
         User = self.classes.User
         s = fixture_session()