]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
skip in eager row processors for enable_eagerloads=False
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 1 Aug 2024 19:58:57 +0000 (15:58 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 1 Aug 2024 21:41:06 +0000 (17:41 -0400)
Fixed issue where using the :meth:`_orm.Query.enable_eagerloads` and
:meth:`_orm.Query.yield_per` methods at the same time, in order to disable
eager loading that's configured on the mapper directly, would be silently
ignored, leading to errors or unexpected eager population of attributes.

Fixes: #10834
Change-Id: I6a20bdedf23f6dd4e98ffb49ad784117fe4afdd3

doc/build/changelog/unreleased_20/10834.rst [new file with mode: 0644]
lib/sqlalchemy/orm/strategies.py
test/orm/test_query.py

diff --git a/doc/build/changelog/unreleased_20/10834.rst b/doc/build/changelog/unreleased_20/10834.rst
new file mode 100644 (file)
index 0000000..7670f57
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 10834
+
+    Fixed issue where using the :meth:`_orm.Query.enable_eagerloads` and
+    :meth:`_orm.Query.yield_per` methods at the same time, in order to disable
+    eager loading that's configured on the mapper directly, would be silently
+    ignored, leading to errors or unexpected eager population of attributes.
index e5eff56f3bfbfc928c8e1b140b8a32f00c86d895..5adbc5f12508a98a9f683b8176c571a5294bd9ee 100644 (file)
@@ -1377,12 +1377,16 @@ class ImmediateLoader(PostLoader):
         adapter,
         populators,
     ):
+        if not context.compile_state.compile_options._enable_eagerloads:
+            return
+
         (
             effective_path,
             run_loader,
             execution_options,
             recursion_depth,
         ) = self._setup_for_recursion(context, path, loadopt, self.join_depth)
+
         if not run_loader:
             # this will not emit SQL and will only emit for a many-to-one
             # "use get" load.   the "_RELATED" part means it may return
@@ -2768,6 +2772,10 @@ class JoinedLoader(AbstractRelationshipLoader):
         adapter,
         populators,
     ):
+
+        if not context.compile_state.compile_options._enable_eagerloads:
+            return
+
         if not self.parent.class_manager[self.key].impl.supports_population:
             raise sa_exc.InvalidRequestError(
                 "'%s' does not support object "
@@ -3047,6 +3055,9 @@ class SelectInLoader(PostLoader, util.MemoizedSlots):
         if not run_loader:
             return
 
+        if not context.compile_state.compile_options._enable_eagerloads:
+            return
+
         if not self.parent.class_manager[self.key].impl.supports_population:
             raise sa_exc.InvalidRequestError(
                 "'%s' does not support object "
index c5fa993d017f13ce0aee0f2d2d0d55b8921242a0..e86283de30c1a0cd192dc4e19551b6867fd0c5f8 100644 (file)
@@ -5540,6 +5540,25 @@ class YieldTest(_fixtures.FixtureTest):
         )
         eq_(len(q.all()), 4)
 
+    @testing.combinations(
+        "joined",
+        "subquery",
+        "selectin",
+        "select",
+        "immediate",
+        argnames="lazy",
+    )
+    def test_eagerload_config_disable(self, lazy):
+        self._eagerload_mappings(addresses_lazy=lazy)
+
+        User = self.classes.User
+        sess = fixture_session()
+        q = sess.query(User).enable_eagerloads(False).yield_per(1)
+        objs = q.all()
+        eq_(len(objs), 4)
+        for obj in objs:
+            assert "addresses" not in obj.__dict__
+
     def test_m2o_joinedload_not_others(self):
         self._eagerload_mappings(addresses_lazy="joined")
         Address = self.classes.Address