]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Handle cache key for option that has no strategy
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 22 Aug 2017 22:35:09 +0000 (18:35 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 22 Aug 2017 22:35:09 +0000 (18:35 -0400)
Fixed regression where the use of a :func:`.undefer_group` option
in conjunction with a lazy loaded relationship option would cause
an attribute error, due to a bug in the SQL cache key generation
added in 1.2 as part of :ticket:`3954`.

Change-Id: Icd9a34f0b5aa96d6433a2ab9c8d3eaee0006f609
Fixes: #4049
doc/build/changelog/unreleased_12/4049.rst [new file with mode: 0644]
lib/sqlalchemy/orm/strategy_options.py
test/orm/test_deferred.py
test/orm/test_options.py

diff --git a/doc/build/changelog/unreleased_12/4049.rst b/doc/build/changelog/unreleased_12/4049.rst
new file mode 100644 (file)
index 0000000..010d1a2
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, orm
+    :tickets: 4049
+
+    Fixed regression where the use of a :func:`.undefer_group` option
+    in conjunction with a lazy loaded relationship option would cause
+    an attribute error, due to a bug in the SQL cache key generation
+    added in 1.2 as part of :ticket:`3954`.
\ No newline at end of file
index c47536a02d121f7f71421fa9536023ae15601530..e07a6b3d0e3bbf8510e04f5bf549a4bad6021d27 100644 (file)
@@ -110,7 +110,7 @@ class Load(Generative, MapperOption):
             serialized.append(
                 (
                     tuple(serialized_path) +
-                    obj.strategy +
+                    (obj.strategy or ()) +
                     (tuple([
                         (key, obj.local_opts[key])
                         for key in sorted(obj.local_opts)
index 9295399bccf4b00a9b61aac0f461d2ab961f90d8..21f40a39af26c338e73442a9b9f769f21ff8a9c1 100644 (file)
@@ -387,6 +387,44 @@ class DeferredOptionsTest(AssertsCompiledSQL, _fixtures.FixtureTest):
              "FROM orders ORDER BY orders.id",
              {})])
 
+    def test_undefer_group_from_relationship_lazyload(self):
+        users, Order, User, orders = \
+            (self.tables.users,
+             self.classes.Order,
+             self.classes.User,
+             self.tables.orders)
+
+        mapper(User, users, properties=dict(
+            orders=relationship(Order, order_by=orders.c.id)))
+        mapper(
+            Order, orders, properties=util.OrderedDict([
+                ('userident', deferred(orders.c.user_id, group='primary')),
+                ('description', deferred(orders.c.description,
+                 group='primary')),
+                ('opened', deferred(orders.c.isopen, group='primary'))
+            ])
+        )
+
+        sess = create_session()
+        q = sess.query(User).filter(User.id == 7).options(
+            defaultload(User.orders).undefer_group('primary')
+        )
+
+        def go():
+            result = q.all()
+            o2 = result[0].orders[1]
+            eq_(o2.opened, 1)
+            eq_(o2.userident, 7)
+            eq_(o2.description, 'order 3')
+        self.sql_eq_(go, [
+            ("SELECT users.id AS users_id, users.name AS users_name "
+             "FROM users WHERE users.id = :id_1", {"id_1": 7}),
+            ("SELECT orders.user_id AS orders_user_id, orders.description "
+             "AS orders_description, orders.isopen AS orders_isopen, "
+             "orders.id AS orders_id, orders.address_id AS orders_address_id "
+             "FROM orders WHERE :param_1 = orders.user_id ORDER BY orders.id",
+             {'param_1': 7})])
+
     def test_undefer_star(self):
         orders, Order = self.tables.orders, self.classes.Order
 
index 024806d4297769e1c21df8a3a798044dbc60afd2..44ebe81c37fb5286e98baa6a29eb6b029dd5a58e 100644 (file)
@@ -1393,3 +1393,32 @@ class CacheKeyTest(PathTest, QueryTest):
             )
         )
 
+    def test_unbound_cache_key_undefer_group(self):
+        User, Address = self.classes('User', 'Address')
+
+        query_path = self._make_path_registry([User, "addresses"])
+
+        opt = defaultload(User.addresses).undefer_group('xyz')
+
+        eq_(
+            opt._generate_cache_key(query_path),
+
+            (
+                (Address, 'column:*', ("undefer_group_xyz", True)),
+            )
+        )
+
+    def test_bound_cache_key_undefer_group(self):
+        User, Address = self.classes('User', 'Address')
+
+        query_path = self._make_path_registry([User, "addresses"])
+
+        opt = Load(User).defaultload(User.addresses).undefer_group('xyz')
+
+        eq_(
+            opt._generate_cache_key(query_path),
+
+            (
+                (Address, 'column:*', ("undefer_group_xyz", True)),
+            )
+        )