]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
handle non-mapped mixins for with_loader_criteria reduce
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 9 Jun 2022 12:55:14 +0000 (08:55 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 9 Jun 2022 12:57:09 +0000 (08:57 -0400)
special handling is needed for a with_loader_criteria()
against a non-mapped mixin class.  added that to test
coverage

Fixes: #8109
Change-Id: Ia599361c8faab008e92095eb4607d02820f590d5
(cherry picked from commit 6f93f88b5ee683141c81ecd434a4c0818e08dbd9)

lib/sqlalchemy/orm/util.py
lib/sqlalchemy/testing/pickleable.py
test/orm/test_pickled.py

index 66f42ba810f02ddb2c2de71f186d0eb13d4d3ee3..f95af41d24a3d7fce66e4ffe7da115d7fbc356f5 100644 (file)
@@ -1174,7 +1174,7 @@ class LoaderCriteriaOption(CriteriaOption):
         return (
             LoaderCriteriaOption._unreduce,
             (
-                self.entity.class_ if self.entity else None,
+                self.entity.class_ if self.entity else self.root_entity,
                 self._where_crit_orig,
                 self.include_aliases,
                 self.propagate_to_loaders,
index 04405e539749e3277b4c3d3681b00df00b2a11cb..f05960c839abca5cc8fb3d81d877e7750b7d604f 100644 (file)
@@ -10,6 +10,8 @@ unpickling.
 """
 
 from . import fixtures
+from ..schema import Column
+from ..types import String
 
 
 class User(fixtures.ComparableEntity):
@@ -51,6 +53,14 @@ class Screen(object):
         self.parent = parent
 
 
+class Mixin(object):
+    email_address = Column(String)
+
+
+class AddressWMixin(Mixin, fixtures.ComparableEntity):
+    pass
+
+
 class Foo(object):
     def __init__(self, moredata, stuff="im stuff"):
         self.data = "im data"
index c1be0ca25c83269cdfe1d906ef8dc5c97be9cb7e..fe7ac7b70289e85a2692c0927e056a5f284f1520 100644 (file)
@@ -24,10 +24,12 @@ from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing.fixtures import fixture_session
 from sqlalchemy.testing.pickleable import Address
+from sqlalchemy.testing.pickleable import AddressWMixin
 from sqlalchemy.testing.pickleable import Child1
 from sqlalchemy.testing.pickleable import Child2
 from sqlalchemy.testing.pickleable import Dingaling
 from sqlalchemy.testing.pickleable import EmailUser
+from sqlalchemy.testing.pickleable import Mixin
 from sqlalchemy.testing.pickleable import Order
 from sqlalchemy.testing.pickleable import Parent
 from sqlalchemy.testing.pickleable import Screen
@@ -331,23 +333,27 @@ class PickleTest(fixtures.MappedTest):
 
     @testing.requires.python3
     @testing.combinations(True, False, argnames="pickle_it")
-    def test_loader_criteria(self, pickle_it):
+    @testing.combinations(True, False, argnames="use_mixin")
+    def test_loader_criteria(self, pickle_it, use_mixin):
         """test #8109"""
 
         users, addresses = (self.tables.users, self.tables.addresses)
 
+        AddressCls = AddressWMixin if use_mixin else Address
+
         self.mapper_registry.map_imperatively(
             User,
             users,
-            properties={"addresses": relationship(Address)},
+            properties={"addresses": relationship(AddressCls)},
         )
-        self.mapper_registry.map_imperatively(Address, addresses)
+
+        self.mapper_registry.map_imperatively(AddressCls, addresses)
 
         with fixture_session(expire_on_commit=False) as sess:
             u1 = User(name="ed")
             u1.addresses = [
-                Address(email_address="ed@bar.com"),
-                Address(email_address="ed@foo.com"),
+                AddressCls(email_address="ed@bar.com"),
+                AddressCls(email_address="ed@foo.com"),
             ]
             sess.add(u1)
             sess.commit()
@@ -356,8 +362,9 @@ class PickleTest(fixtures.MappedTest):
             # note that non-lambda is not picklable right now as
             # SQL expressions usually can't be pickled.
             opt = with_loader_criteria(
-                Address,
+                Mixin if use_mixin else Address,
                 no_ed_foo,
+                include_aliases=True,
             )
 
             u1 = sess.query(User).options(opt).first()