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
-----------------
: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.
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
# 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)