diff options
Diffstat (limited to 'lib/sqlalchemy/orm/interfaces.py')
-rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 105 |
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 |