]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- rewrite the docs and add a test for the bake_queries=True
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 19 Nov 2015 19:23:08 +0000 (14:23 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 19 Nov 2015 19:23:08 +0000 (14:23 -0500)
relationship flag; this flag *does* have an effect when the baked
lazy loader plugin has been invoked.  clarify the intent of this
flag as an "opt out" but only has an effect when the baked system
is loaded anyway.  fixes #3572

doc/build/orm/extensions/baked.rst
lib/sqlalchemy/orm/relationships.py
test/ext/test_baked.py

index a282d1298d1e4db37994d5a6b74c3823b6710383..83cee51dace5bae29b4b4234d071ed725d0b0612 100644 (file)
@@ -355,6 +355,14 @@ this feature is local to the mapper for ``MyClass``.
 For per-query use, the :func:`.baked_lazyload` strategy may be used,
 which works like any other loader option.
 
+Opting out with the bake_queries flag
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :func:`.relationship` construct includes a flag
+:paramref:`.relationship.bake_queries` which when set to False will cause
+that relationship to opt out of the baked query system, when the
+application-wide :func:`.bake_lazy_loaders` function has been called to enable
+baked query loaders by default.
 
 API Documentation
 -----------------
index 552ce8b69bbad821976d0a9757e830dc695f7294..929c923a604d98a40dfb1165948af2198bb08788 100644 (file)
@@ -275,15 +275,31 @@ class RelationshipProperty(StrategizedProperty):
             :paramref:`~.relationship.backref` - alternative form
             of backref specification.
 
-        :param bake_queries:
-          Use the :class:`.BakedQuery` cache to cache queries used in lazy
-          loads.  True by default, as this typically improves performance
-          significantly.  Set to False to reduce ORM memory use, or
-          if unresolved stability issues are observed with the baked query
+        :param bake_queries=True:
+          Use the :class:`.BakedQuery` cache to cache the construction of SQL
+          used in lazy loads, when the :func:`.bake_lazy_loaders` function has
+          first been called.  Defaults to True and is intended to provide an
+          "opt out" flag per-relationship when the baked query cache system is
+          in use.
+
+          .. warning::
+
+              This flag **only** has an effect when the application-wide
+              :func:`.bake_lazy_loaders` function has been called.   It
+              defaults to True so is an "opt out" flag.
+
+          Setting this flag to False when baked queries are otherwise in
+          use might be to reduce
+          ORM memory use for this :func:`.relationship`, or to work around
+          unresolved stability issues observed within the baked query
           cache system.
 
           .. versionadded:: 1.0.0
 
+          .. seealso::
+
+            :ref:`baked_toplevel`
+
         :param cascade:
           a comma-separated list of cascade rules which determines how
           Session operations should be "cascaded" from parent to child.
index 8bf697fbfb612fb04ce7b9ddcf358b8fae69d665..dcf333184c9c6d053a1d392051af658eb9b9957c 100644 (file)
@@ -596,14 +596,14 @@ class ResultTest(BakedTest):
 class LazyLoaderTest(BakedTest):
     run_setup_mappers = 'each'
 
-    def _o2m_fixture(self, lazy="select"):
+    def _o2m_fixture(self, lazy="select", **kw):
         User = self.classes.User
         Address = self.classes.Address
 
         mapper(User, self.tables.users, properties={
             'addresses': relationship(
                 Address, order_by=self.tables.addresses.c.id,
-                lazy=lazy)
+                lazy=lazy, **kw)
         })
         mapper(Address, self.tables.addresses)
         return User, Address
@@ -720,6 +720,50 @@ class LazyLoaderTest(BakedTest):
             # not invoked
             eq_(el.mock_calls, [])
 
+    def test_baked_lazy_loading_relationship_flag_true(self):
+        self._test_baked_lazy_loading_relationship_flag(True)
+
+    def test_baked_lazy_loading_relationship_flag_false(self):
+        self._test_baked_lazy_loading_relationship_flag(False)
+
+    def _test_baked_lazy_loading_relationship_flag(self, flag):
+        baked.bake_lazy_loaders()
+        try:
+            User, Address = self._o2m_fixture(bake_queries=flag)
+
+            sess = Session()
+            u1 = sess.query(User).first()
+
+            from sqlalchemy.orm import Query
+
+            canary = mock.Mock()
+
+            # I would think Mock can do this but apparently
+            # it cannot (wrap / autospec don't work together)
+            real_compile_context = Query._compile_context
+
+            def _my_compile_context(*arg, **kw):
+                if arg[0].column_descriptions[0]['entity'] is Address:
+                    canary()
+                return real_compile_context(*arg, **kw)
+
+            with mock.patch.object(
+                Query,
+                "_compile_context",
+                _my_compile_context
+            ):
+                u1.addresses
+
+                sess.expire(u1)
+                u1.addresses
+        finally:
+            baked.unbake_lazy_loaders()
+
+        if flag:
+            eq_(canary.call_count, 1)
+        else:
+            eq_(canary.call_count, 2)
+
     def test_baked_lazy_loading_option_o2m(self):
         User, Address = self._o2m_fixture()
         self._test_baked_lazy_loading(set_option=True)