summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/interfaces.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/interfaces.py')
-rw-r--r--lib/sqlalchemy/orm/interfaces.py105
1 files changed, 59 insertions, 46 deletions
diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py
index 313f2fda8..6c0f5d3ef 100644
--- a/lib/sqlalchemy/orm/interfaces.py
+++ b/lib/sqlalchemy/orm/interfaces.py
@@ -64,6 +64,12 @@ __all__ = (
)
+class ORMStatementRole(roles.CoerceTextStatementRole):
+ _role_name = (
+ "Executable SQL or text() construct, including ORM " "aware objects"
+ )
+
+
class ORMColumnsClauseRole(roles.ColumnsClauseRole):
_role_name = "ORM mapped entity, aliased entity, or Column expression"
@@ -662,8 +668,15 @@ class StrategizedProperty(MapperProperty):
)
-class LoaderOption(HasCacheKey):
- """Describe a modification to an ORM statement at compilation time.
+class ORMOption(object):
+ """Base class for option objects that are passed to ORM queries.
+
+ These options may be consumed by :meth:`.Query.options`,
+ :meth:`.Select.options`, or in a more general sense by any
+ :meth:`.Executable.options` method. They are interpreted at
+ statement compile time or execution time in modern use. The
+ deprecated :class:`.MapperOption` is consumed at ORM query construction
+ time.
.. versionadded:: 1.4
@@ -680,6 +693,18 @@ class LoaderOption(HasCacheKey):
"""
+ _is_compile_state = False
+
+
+class LoaderOption(HasCacheKey, ORMOption):
+ """Describe a loader modification to an ORM statement at compilation time.
+
+ .. versionadded:: 1.4
+
+ """
+
+ _is_compile_state = True
+
def process_compile_state(self, compile_state):
"""Apply a modification to a given :class:`.CompileState`."""
@@ -693,18 +718,39 @@ class LoaderOption(HasCacheKey):
return False
+class UserDefinedOption(ORMOption):
+ """Base class for a user-defined option that can be consumed from the
+ :meth:`.SessionEvents.do_orm_execute` event hook.
+
+ """
+
+ _is_legacy_option = False
+
+ propagate_to_loaders = False
+ """if True, indicate this option should be carried along
+ to "secondary" Query objects produced during lazy loads
+ or refresh operations.
+
+ """
+
+ def __init__(self, payload=None):
+ self.payload = payload
+
+ def _gen_cache_key(self, *arg, **kw):
+ return ()
+
+
@util.deprecated_cls(
"1.4",
"The :class:`.MapperOption class is deprecated and will be removed "
- "in a future release. ORM options now run within the compilation "
- "phase and are based on the :class:`.LoaderOption` class which is "
- "intended for internal consumption only. For "
- "modifications to queries on a per-execution basis, the "
- ":meth:`.before_execute` hook will now intercept ORM :class:`.Query` "
- "objects before they are invoked",
+ "in a future release. For "
+ "modifications to queries on a per-execution basis, use the "
+ ":class:`.UserDefinedOption` class to establish state within a "
+ ":class:`.Query` or other Core statement, then use the "
+ ":meth:`.SessionEvents.before_orm_execute` hook to consume them.",
constructor=None,
)
-class MapperOption(object):
+class MapperOption(ORMOption):
"""Describe a modification to a Query"""
_is_legacy_option = True
@@ -735,23 +781,6 @@ class MapperOption(object):
def _generate_path_cache_key(self, path):
"""Used by the "baked lazy loader" to see if this option can be cached.
- The "baked lazy loader" refers to the :class:`_query.Query` that is
- produced during a lazy load operation for a mapped relationship.
- It does not yet apply to the "lazy" load operation for deferred
- or expired column attributes, however this may change in the future.
-
- This loader generates SQL for a query only once and attempts to cache
- it; from that point on, if the SQL has been cached it will no longer
- run the :meth:`_query.Query.options` method of the
- :class:`_query.Query`. The
- :class:`.MapperOption` object that wishes to participate within a lazy
- load operation therefore needs to tell the baked loader that it either
- needs to forego this caching, or that it needs to include the state of
- the :class:`.MapperOption` itself as part of its cache key, otherwise
- SQL or other query state that has been affected by the
- :class:`.MapperOption` may be cached in place of a query that does not
- include these modifications, or the option may not be invoked at all.
-
By default, this method returns the value ``False``, which means
the :class:`.BakedQuery` generated by the lazy loader will
not cache the SQL when this :class:`.MapperOption` is present.
@@ -760,26 +789,10 @@ class MapperOption(object):
an unlimited number of :class:`_query.Query` objects for an unlimited
number of :class:`.MapperOption` objects.
- .. versionchanged:: 1.2.8 the default return value of
- :meth:`.MapperOption._generate_cache_key` is False; previously it
- was ``None`` indicating "safe to cache, don't include as part of
- the cache key"
-
- To enable caching of :class:`_query.Query` objects within lazy loaders
- , a
- given :class:`.MapperOption` that returns a cache key must return a key
- that uniquely identifies the complete state of this option, which will
- match any other :class:`.MapperOption` that itself retains the
- identical state. This includes path options, flags, etc. It should
- be a state that is repeatable and part of a limited set of possible
- options.
-
- If the :class:`.MapperOption` does not apply to the given path and
- would not affect query results on such a path, it should return None,
- indicating the :class:`_query.Query` is safe to cache for this given
- loader path and that this :class:`.MapperOption` need not be
- part of the cache key.
-
+ For caching support it is recommended to use the
+ :class:`.UserDefinedOption` class in conjunction with
+ the :meth:`.Session.do_orm_execute` method so that statements may
+ be modified before they are cached.
"""
return False