summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/orm/__init__.py1
-rw-r--r--lib/sqlalchemy/orm/relationships.py4
-rw-r--r--lib/sqlalchemy/orm/strategies.py27
-rw-r--r--lib/sqlalchemy/orm/strategy_options.py23
4 files changed, 55 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index e02a271e3..c18692095 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -237,6 +237,7 @@ subqueryload = strategy_options.subqueryload._unbound_fn
subqueryload_all = strategy_options.subqueryload_all._unbound_all_fn
immediateload = strategy_options.immediateload._unbound_fn
noload = strategy_options.noload._unbound_fn
+raiseload = strategy_options.raiseload._unbound_fn
defaultload = strategy_options.defaultload._unbound_fn
from .strategy_options import Load
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py
index da0730f46..251930873 100644
--- a/lib/sqlalchemy/orm/relationships.py
+++ b/lib/sqlalchemy/orm/relationships.py
@@ -524,6 +524,10 @@ class RelationshipProperty(StrategizedProperty):
support "write-only" attributes, or attributes which are
populated in some manner specific to the application.
+ * ``raise`` - no loading should occur at any time, and accessing
+ the attribute will fail with an
+ :exc:`~sqlalchemy.exc.InvalidRequestError`.
+
* ``dynamic`` - the attribute will return a pre-configured
:class:`.Query` object for all read
operations, onto which further filtering operations can be
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index 67dac1ccc..8fc0a8d68 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -354,6 +354,33 @@ class NoLoader(AbstractRelationshipLoader):
@log.class_logger
+@properties.RelationshipProperty.strategy_for(lazy="raise")
+class RaiseLoader(NoLoader):
+ """Provide loading behavior for a :class:`.RelationshipProperty`
+ with "lazy='raise'".
+
+ """
+
+ __slots__ = ()
+
+ def create_row_processor(
+ self, context, path, loadopt, mapper,
+ result, adapter, populators):
+
+ def invoke_raise_load(state, passive):
+ raise sa_exc.InvalidRequestError(
+ "'%s' is not available due to lazy='raise'" % self
+ )
+
+ set_lazy_callable = InstanceState._instance_level_callable_processor(
+ mapper.class_manager,
+ invoke_raise_load,
+ self.key
+ )
+ populators["new"].append((self.key, set_lazy_callable))
+
+
+@log.class_logger
@properties.RelationshipProperty.strategy_for(lazy=True)
@properties.RelationshipProperty.strategy_for(lazy="select")
class LazyLoader(AbstractRelationshipLoader, util.MemoizedSlots):
diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py
index cb7a5fef7..5b2a190b9 100644
--- a/lib/sqlalchemy/orm/strategy_options.py
+++ b/lib/sqlalchemy/orm/strategy_options.py
@@ -854,6 +854,29 @@ def noload(*keys):
@loader_option()
+def raiseload(loadopt, attr):
+ """Indicate that the given relationship attribute should remain unloaded.
+
+ Accessing the relationship attribute anyway raises an
+ :exc:`~sqlalchemy.exc.InvalidRequestError`.
+
+ This function is part of the :class:`.Load` interface and supports
+ both method-chained and standalone operation.
+
+ :func:`.orm.raiseload` applies to :func:`.relationship` attributes only.
+
+ .. versionadded:: 1.1.0
+ """
+
+ return loadopt.set_relationship_strategy(attr, {"lazy": "raise"})
+
+
+@raiseload._add_unbound_fn
+def raiseload(*keys):
+ return _UnboundLoad._from_keys(_UnboundLoad.raiseload, keys, False, {})
+
+
+@loader_option()
def defaultload(loadopt, attr):
"""Indicate an attribute should load using its default loader style.