diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-04-29 19:46:43 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-31 21:41:52 -0400 |
commit | 4ecd352a9fbb9dbac7b428fe0f098f665c1f0cb1 (patch) | |
tree | 323868c9f18fffdbfef6168622010c7d19367b12 /lib/sqlalchemy/sql/selectable.py | |
parent | cbfa1363d7201848a56e7209146e81b9c51aa8af (diff) | |
download | sqlalchemy-4ecd352a9fbb9dbac7b428fe0f098f665c1f0cb1.tar.gz |
Improve rendering of core statements w/ ORM elements
This patch contains a variety of ORM and expression layer
tweaks to support ORM constructs in select() statements,
without the 1.3.x requiremnt in Query that a full
_compile_context() + new select() is needed in order to
get a working statement object.
Includes such tweaks as the ability to implement
aliased class of an aliased class,
as we are looking to fully support ACs against subqueries,
as well as the ability to access anonymously-labeled
ColumnProperty expressions within subqueries by
naming the ".key" of the label after the property
key. Some tuning to query.join() as well
as ORMJoin internals to allow things to work more
smoothly.
Change-Id: Id810f485c5f7ed971529489b84694e02a3356d6d
Diffstat (limited to 'lib/sqlalchemy/sql/selectable.py')
-rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 170e016a5..d6845e05f 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -3451,8 +3451,8 @@ class SelectState(util.MemoizedSlots, CompileState): self.columns_plus_names = statement._generate_columns_plus_names(True) def _get_froms(self, statement): - froms = [] seen = set() + froms = [] for item in itertools.chain( itertools.chain.from_iterable( @@ -3474,6 +3474,16 @@ class SelectState(util.MemoizedSlots, CompileState): froms.append(item) seen.update(item._cloned_set) + toremove = set( + itertools.chain.from_iterable( + [_expand_cloned(f._hide_froms) for f in froms] + ) + ) + if toremove: + # filter out to FROM clauses not in the list, + # using a list to maintain ordering + froms = [f for f in froms if f not in toremove] + return froms def _get_display_froms( @@ -3490,16 +3500,6 @@ class SelectState(util.MemoizedSlots, CompileState): froms = self.froms - toremove = set( - itertools.chain.from_iterable( - [_expand_cloned(f._hide_froms) for f in froms] - ) - ) - if toremove: - # filter out to FROM clauses not in the list, - # using a list to maintain ordering - froms = [f for f in froms if f not in toremove] - if self.statement._correlate: to_correlate = self.statement._correlate if to_correlate: @@ -3557,7 +3557,7 @@ class SelectState(util.MemoizedSlots, CompileState): def _memoized_attr__label_resolve_dict(self): with_cols = dict( (c._resolve_label or c._label or c.key, c) - for c in _select_iterables(self.statement._raw_columns) + for c in self.statement._exported_columns_iterator() if c._allow_label_resolve ) only_froms = dict( @@ -3578,6 +3578,10 @@ class SelectState(util.MemoizedSlots, CompileState): else: return None + @classmethod + def exported_columns_iterator(cls, statement): + return _select_iterables(statement._raw_columns) + def _setup_joins(self, args): for (right, onclause, left, flags) in args: isouter = flags["isouter"] @@ -4599,7 +4603,7 @@ class Select( pa = None collection = [] - for c in _select_iterables(self._raw_columns): + for c in self._exported_columns_iterator(): # we use key_label since this name is intended for targeting # within the ColumnCollection only, it's not related to SQL # rendering which always uses column name for SQL label names @@ -4630,7 +4634,7 @@ class Select( return self def _generate_columns_plus_names(self, anon_for_dupe_key): - cols = _select_iterables(self._raw_columns) + cols = self._exported_columns_iterator() # when use_labels is on: # in all cases == if we see the same label name, use _label_anon_label |