This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# sql/cache_key.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
@@ -11,6 +11,7 @@ import enum
|
||||
from itertools import zip_longest
|
||||
import typing
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import Iterator
|
||||
@@ -36,6 +37,7 @@ from ..util.typing import Protocol
|
||||
if typing.TYPE_CHECKING:
|
||||
from .elements import BindParameter
|
||||
from .elements import ClauseElement
|
||||
from .elements import ColumnElement
|
||||
from .visitors import _TraverseInternalsType
|
||||
from ..engine.interfaces import _CoreSingleExecuteParams
|
||||
|
||||
@@ -43,8 +45,7 @@ if typing.TYPE_CHECKING:
|
||||
class _CacheKeyTraversalDispatchType(Protocol):
|
||||
def __call__(
|
||||
s, self: HasCacheKey, visitor: _CacheKeyTraversal
|
||||
) -> CacheKey:
|
||||
...
|
||||
) -> _CacheKeyTraversalDispatchTypeReturn: ...
|
||||
|
||||
|
||||
class CacheConst(enum.Enum):
|
||||
@@ -75,6 +76,18 @@ class CacheTraverseTarget(enum.Enum):
|
||||
ANON_NAME,
|
||||
) = tuple(CacheTraverseTarget)
|
||||
|
||||
_CacheKeyTraversalDispatchTypeReturn = Sequence[
|
||||
Tuple[
|
||||
str,
|
||||
Any,
|
||||
Union[
|
||||
Callable[..., Tuple[Any, ...]],
|
||||
CacheTraverseTarget,
|
||||
InternalTraversal,
|
||||
],
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
class HasCacheKey:
|
||||
"""Mixin for objects which can produce a cache key.
|
||||
@@ -290,11 +303,13 @@ class HasCacheKey:
|
||||
result += (
|
||||
attrname,
|
||||
obj["compile_state_plugin"],
|
||||
obj["plugin_subject"]._gen_cache_key(
|
||||
anon_map, bindparams
|
||||
)
|
||||
if obj["plugin_subject"]
|
||||
else None,
|
||||
(
|
||||
obj["plugin_subject"]._gen_cache_key(
|
||||
anon_map, bindparams
|
||||
)
|
||||
if obj["plugin_subject"]
|
||||
else None
|
||||
),
|
||||
)
|
||||
elif meth is InternalTraversal.dp_annotations_key:
|
||||
# obj is here is the _annotations dict. Table uses
|
||||
@@ -324,7 +339,7 @@ class HasCacheKey:
|
||||
),
|
||||
)
|
||||
else:
|
||||
result += meth(
|
||||
result += meth( # type: ignore
|
||||
attrname, obj, self, anon_map, bindparams
|
||||
)
|
||||
return result
|
||||
@@ -501,7 +516,7 @@ class CacheKey(NamedTuple):
|
||||
e2,
|
||||
)
|
||||
else:
|
||||
pickup_index = stack.pop(-1)
|
||||
stack.pop(-1)
|
||||
break
|
||||
|
||||
def _diff(self, other: CacheKey) -> str:
|
||||
@@ -543,18 +558,17 @@ class CacheKey(NamedTuple):
|
||||
_anon_map = prefix_anon_map()
|
||||
return {b.key % _anon_map: b.effective_value for b in self.bindparams}
|
||||
|
||||
@util.preload_module("sqlalchemy.sql.elements")
|
||||
def _apply_params_to_element(
|
||||
self, original_cache_key: CacheKey, target_element: ClauseElement
|
||||
) -> ClauseElement:
|
||||
if target_element._is_immutable:
|
||||
self, original_cache_key: CacheKey, target_element: ColumnElement[Any]
|
||||
) -> ColumnElement[Any]:
|
||||
if target_element._is_immutable or original_cache_key is self:
|
||||
return target_element
|
||||
|
||||
translate = {
|
||||
k.key: v.value
|
||||
for k, v in zip(original_cache_key.bindparams, self.bindparams)
|
||||
}
|
||||
|
||||
return target_element.params(translate)
|
||||
elements = util.preloaded.sql_elements
|
||||
return elements._OverrideBinds(
|
||||
target_element, self.bindparams, original_cache_key.bindparams
|
||||
)
|
||||
|
||||
|
||||
def _ad_hoc_cache_key_from_args(
|
||||
@@ -606,9 +620,9 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
InternalTraversal.dp_memoized_select_entities
|
||||
)
|
||||
|
||||
visit_string = (
|
||||
visit_boolean
|
||||
) = visit_operator = visit_plain_obj = CACHE_IN_PLACE
|
||||
visit_string = visit_boolean = visit_operator = visit_plain_obj = (
|
||||
CACHE_IN_PLACE
|
||||
)
|
||||
visit_statement_hint_list = CACHE_IN_PLACE
|
||||
visit_type = STATIC_CACHE_KEY
|
||||
visit_anon_name = ANON_NAME
|
||||
@@ -655,9 +669,11 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
) -> Tuple[Any, ...]:
|
||||
return (
|
||||
attrname,
|
||||
obj._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(obj, HasCacheKey)
|
||||
else obj,
|
||||
(
|
||||
obj._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(obj, HasCacheKey)
|
||||
else obj
|
||||
),
|
||||
)
|
||||
|
||||
def visit_multi_list(
|
||||
@@ -671,9 +687,11 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
return (
|
||||
attrname,
|
||||
tuple(
|
||||
elem._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(elem, HasCacheKey)
|
||||
else elem
|
||||
(
|
||||
elem._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(elem, HasCacheKey)
|
||||
else elem
|
||||
)
|
||||
for elem in obj
|
||||
),
|
||||
)
|
||||
@@ -834,12 +852,16 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
return tuple(
|
||||
(
|
||||
target._gen_cache_key(anon_map, bindparams),
|
||||
onclause._gen_cache_key(anon_map, bindparams)
|
||||
if onclause is not None
|
||||
else None,
|
||||
from_._gen_cache_key(anon_map, bindparams)
|
||||
if from_ is not None
|
||||
else None,
|
||||
(
|
||||
onclause._gen_cache_key(anon_map, bindparams)
|
||||
if onclause is not None
|
||||
else None
|
||||
),
|
||||
(
|
||||
from_._gen_cache_key(anon_map, bindparams)
|
||||
if from_ is not None
|
||||
else None
|
||||
),
|
||||
tuple([(key, flags[key]) for key in sorted(flags)]),
|
||||
)
|
||||
for (target, onclause, from_, flags) in obj
|
||||
@@ -933,9 +955,11 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
tuple(
|
||||
(
|
||||
key,
|
||||
value._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(value, HasCacheKey)
|
||||
else value,
|
||||
(
|
||||
value._gen_cache_key(anon_map, bindparams)
|
||||
if isinstance(value, HasCacheKey)
|
||||
else value
|
||||
),
|
||||
)
|
||||
for key, value in [(key, obj[key]) for key in sorted(obj)]
|
||||
),
|
||||
@@ -981,9 +1005,11 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
attrname,
|
||||
tuple(
|
||||
(
|
||||
key._gen_cache_key(anon_map, bindparams)
|
||||
if hasattr(key, "__clause_element__")
|
||||
else key,
|
||||
(
|
||||
key._gen_cache_key(anon_map, bindparams)
|
||||
if hasattr(key, "__clause_element__")
|
||||
else key
|
||||
),
|
||||
value._gen_cache_key(anon_map, bindparams),
|
||||
)
|
||||
for key, value in obj
|
||||
@@ -1004,9 +1030,11 @@ class _CacheKeyTraversal(HasTraversalDispatch):
|
||||
attrname,
|
||||
tuple(
|
||||
(
|
||||
k._gen_cache_key(anon_map, bindparams)
|
||||
if hasattr(k, "__clause_element__")
|
||||
else k,
|
||||
(
|
||||
k._gen_cache_key(anon_map, bindparams)
|
||||
if hasattr(k, "__clause_element__")
|
||||
else k
|
||||
),
|
||||
obj[k]._gen_cache_key(anon_map, bindparams),
|
||||
)
|
||||
for k in obj
|
||||
|
||||
Reference in New Issue
Block a user