]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix QueryContext ref cycle on joinedload
authorCarson Ip <carsonip715@gmail.com>
Fri, 3 Jan 2020 22:09:20 +0000 (17:09 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 4 Jan 2020 18:01:26 +0000 (13:01 -0500)
Avoid storing a reference to itself when dealing with create_eager_joins. Also fix a cheating test.

Fixes: #5071
Closes: #5072
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/5072
Pull-request-sha: 75ebaf7c91e96d7567eb5760be713dc134c58763

Change-Id: I511ddc0979b46f7928217347199eca4b1d0b4a49

doc/build/changelog/unreleased_13/5056.rst
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/orm/strategies.py
test/aaa_profiling/test_memusage.py

index 217044c1853fde6515e7c7ffddac746d6fd20123..950cce3c20e478fa78bef2bc7853e6a75eee67ce 100644 (file)
@@ -1,6 +1,6 @@
 .. change::
     :tags: bug, orm, engine
-    :tickets: 5056, 5050
+    :tickets: 5056, 5050, 5071
 
     Added test support and repaired a wide variety of unnecessary reference
     cycles created for short-lived objects, mostly in the area of ORM queries.
index e69ebde56615407671ebc71ca1225e2f4133ea93..5f799cc68b0fe537b334f7f5c7a415a3302102e6 100644 (file)
@@ -3878,7 +3878,7 @@ class Query(Generative):
 
         for rec in context.create_eager_joins:
             strategy = rec[0]
-            strategy(*rec[1:])
+            strategy(context, *rec[1:])
 
         if context.from_clause:
             # "load from explicit FROMs" mode,
index 4f27c23d649ac15f79bd725cd1409bffe160c69c..79e36026c8411796fc4a9913d922d28f169892ba 100644 (file)
@@ -1759,7 +1759,6 @@ class JoinedLoader(AbstractRelationshipLoader):
         context.create_eager_joins.append(
             (
                 self._create_eager_join,
-                context,
                 entity,
                 path,
                 adapter,
index 301724509543626061256beda91014b506467ffc..94d16517e314a6d1deeb50098c508fec7f2739b8 100644 (file)
@@ -1269,6 +1269,21 @@ class CycleTest(_fixtures.FixtureTest):
 
         go()
 
+    def test_query_joinedload(self):
+        User, Address = self.classes("User", "Address")
+
+        s = Session()
+
+        def generate():
+            s.query(User).options(joinedload(User.addresses)).all()
+
+        # cycles here are due to ClauseElement._cloned_set and Load.context
+        @assert_cycles(28)
+        def go():
+            generate()
+
+        go()
+
     def test_plain_join(self):
         users, addresses = self.tables("users", "addresses")