diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sqlalchemy/orm/__init__.py | 1 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/relationships.py | 4 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 27 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/strategy_options.py | 23 |
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. |