diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-04-17 13:37:39 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-04-29 12:45:45 -0400 |
| commit | 08da8115a6eb7eb125fa5f92f662d915b076fded (patch) | |
| tree | a4eaee5acdd2ffd7f254b1426b97e176c6dda803 /lib/sqlalchemy/sql/selectable.py | |
| parent | 099522075088a3e1a333a2285c10a8a33b203c19 (diff) | |
| download | sqlalchemy-08da8115a6eb7eb125fa5f92f662d915b076fded.tar.gz | |
Add _cache_key implementation.
This leverages the work started in #4336 to allow ClauseElement
structures to be cachable based on structure, not just identity.
Change-Id: Ia99ddeb5353496dd7d61243245685f02b98d8100
Diffstat (limited to 'lib/sqlalchemy/sql/selectable.py')
| -rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 796e2b272..a44e94da7 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -864,6 +864,16 @@ class Join(FromClause): def get_children(self, **kwargs): return self.left, self.right, self.onclause + def _cache_key(self, **kw): + return ( + Join, + self.isouter, + self.full, + self.left._cache_key(**kw), + self.right._cache_key(**kw), + self.onclause._cache_key(**kw), + ) + def _match_primaries(self, left, right): if isinstance(left, Join): left_right = left.right @@ -1289,6 +1299,7 @@ class Alias(FromClause): if self.supports_execution: self._execution_options = baseselectable._execution_options self.element = selectable + self._orig_name = name if name is None: if self.original.named_with_column: name = getattr(self.original, "name", None) @@ -1358,6 +1369,9 @@ class Alias(FromClause): yield c yield self.element + def _cache_key(self, **kw): + return (self.__class__, self.element._cache_key(**kw), self._orig_name) + @property def _from_objects(self): return [self] @@ -1777,6 +1791,9 @@ class FromGrouping(FromClause): def _copy_internals(self, clone=_clone, **kw): self.element = clone(self.element, **kw) + def _cache_key(self, **kw): + return (FromGrouping, self.element._cache_key(**kw)) + @property def _from_objects(self): return self.element._from_objects @@ -1877,6 +1894,11 @@ class TableClause(Immutable, FromClause): else: return [] + def _cache_key(self, **kw): + return (TableClause, self.name) + tuple( + col._cache_key(**kw) for col in self._columns + ) + @util.dependencies("sqlalchemy.sql.dml") def insert(self, dml, values=None, inline=False, **kwargs): """Generate an :func:`.insert` construct against this @@ -2004,6 +2026,15 @@ class ForUpdateArg(ClauseElement): if self.of is not None: self.of = [clone(col, **kw) for col in self.of] + def _cache_key(self, **kw): + return ( + ForUpdateArg, + self.nowait, + self.read, + self.skip_locked, + self.of._cache_key(**kw) if self.of is not None else None, + ) + def __init__( self, nowait=False, @@ -2653,6 +2684,27 @@ class CompoundSelect(GenerativeSelect): + list(self.selects) ) + def _cache_key(self, **kw): + return ( + (CompoundSelect, self.keyword) + + tuple(stmt._cache_key(**kw) for stmt in self.selects) + + ( + self._order_by_clause._cache_key(**kw) + if self._order_by_clause is not None + else None, + ) + + ( + self._group_by_clause._cache_key(**kw) + if self._group_by_clause is not None + else None, + ) + + ( + self._for_update_arg._cache_key(**kw) + if self._for_update_arg is not None + else None, + ) + ) + def bind(self): if self._bind: return self._bind @@ -3277,6 +3329,47 @@ class Select(HasPrefixes, HasSuffixes, GenerativeSelect): ] ) + def _cache_key(self, **kw): + return ( + (Select,) + + ("raw_columns",) + + tuple(elem._cache_key(**kw) for elem in self._raw_columns) + + ("elements",) + + tuple( + elem._cache_key(**kw) if elem is not None else None + for elem in ( + self._whereclause, + self._having, + self._order_by_clause, + self._group_by_clause, + ) + ) + + ("from_obj",) + + tuple(elem._cache_key(**kw) for elem in self._from_obj) + + ("correlate",) + + tuple( + elem._cache_key(**kw) + for elem in ( + self._correlate if self._correlate is not None else () + ) + ) + + ("correlate_except",) + + tuple( + elem._cache_key(**kw) + for elem in ( + self._correlate_except + if self._correlate_except is not None + else () + ) + ) + + ("for_update",), + ( + self._for_update_arg._cache_key(**kw) + if self._for_update_arg is not None + else None, + ), + ) + @_generative def column(self, column): """return a new select() construct with the given column expression @@ -3950,6 +4043,11 @@ class TextAsFrom(SelectBase): yield c yield self.element + def _cache_key(self, **kw): + return (TextAsFrom, self.element._cache_key(**kw)) + tuple( + col._cache_key(**kw) for col in self.column_args + ) + def _scalar_type(self): return self.column_args[0].type |
