summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-10-03 15:55:04 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2016-10-04 12:09:29 -0400
commit95d4cd30420414fcede2662aed87b0f2e5a861d4 (patch)
treeb77df1c621fdea15a95a784fae5c76765c117bbd /doc
parent728ce8cc480d0ada690e5a97067cff821b9a65f3 (diff)
downloadsqlalchemy-95d4cd30420414fcede2662aed87b0f2e5a861d4.tar.gz
Enhance "raise" strategy to include "raise_on_sql" option
The "raise_on_sql" option differentiates from "raise" in that firing a lazy loader is OK as long as it does a simple get from identity map. Whereas "raise" is more useful for the case that objects are to be detached. As part of this, refactors the strategy initiation logic a bit so that a LoaderStrategy itself knows what "key" was used to create it, thus allowing variants of a single strategy based on what the "lazy" argument is. To achieve this we have to also get rid of _get_strategy_by_cls(). Everything here is internal with the one exception of an apparently undocumented, but not underscored, "strategy_class" key on relationship(). Though it's not clear what "strategy_class" accomplishes; at this point the strategy system is extensible using Property.strategy_for(). Fixes: #3812 Change-Id: I812ad878ea5cf764e15f6f71cb39eee78a645d88
Diffstat (limited to 'doc')
-rw-r--r--doc/build/changelog/changelog_11.rst10
-rw-r--r--doc/build/changelog/migration_11.rst26
2 files changed, 29 insertions, 7 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst
index a3cc96f99..6e2fc014c 100644
--- a/doc/build/changelog/changelog_11.rst
+++ b/doc/build/changelog/changelog_11.rst
@@ -22,6 +22,16 @@
:version: 1.1.0
.. change::
+ :tags: feature, orm
+ :tickets: 3812
+
+ Enhanced the new "raise" lazy loader strategy to also include a
+ "raise_on_sql" variant, available both via :paramref:`.orm.relationship.lazy`
+ as well as :func:`.orm.raiseload`. This variant only raises if the
+ lazy load would actually emit SQL, vs. raising if the lazy loader
+ mechanism is invoked at all.
+
+ .. change::
:tags: bug, orm
:tickets: 3808
diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst
index e514f4dbb..7f8ead143 100644
--- a/doc/build/changelog/migration_11.rst
+++ b/doc/build/changelog/migration_11.rst
@@ -1019,21 +1019,33 @@ added to the :ref:`mutable_toplevel` extension, to complement the existing
.. _change_3512:
-New "raise" loader strategy
----------------------------
+New "raise" / "raise_on_sql" loader strategies
+----------------------------------------------
To assist with the use case of preventing unwanted lazy loads from occurring
-after a series of objects are loaded, the new "lazy='raise'" strategy and
+after a series of objects are loaded, the new "lazy='raise'" and
+"lazy='raise_on_sql'" strategies and
corresponding loader option :func:`.orm.raiseload` may be applied to a
relationship attribute which will cause it to raise ``InvalidRequestError``
-when a non-eagerly-loaded attribute is accessed for read::
+when a non-eagerly-loaded attribute is accessed for read. The two variants
+test for either a lazy load of any variety, including those that would
+only return None or retrieve from the identity map::
+
+ >>> from sqlalchemy.orm import raiseload
+ >>> a1 = s.query(A).options(raiseload(A.some_b)).first()
+ >>> a1.some_b
+ Traceback (most recent call last):
+ ...
+ sqlalchemy.exc.InvalidRequestError: 'A.some_b' is not available due to lazy='raise'
+
+Or a lazy load only where SQL would be emitted::
>>> from sqlalchemy.orm import raiseload
- >>> a1 = s.query(A).options(raiseload(A.bs)).first()
- >>> a1.bs
+ >>> a1 = s.query(A).options(raiseload(A.some_b, sql_only=True)).first()
+ >>> a1.some_b
Traceback (most recent call last):
...
- sqlalchemy.exc.InvalidRequestError: 'A.bs' is not available due to lazy='raise'
+ sqlalchemy.exc.InvalidRequestError: 'A.bs' is not available due to lazy='raise_on_sql'
:ticket:`3512`