summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/selectable.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-02-26 15:34:49 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-02-26 15:34:49 -0500
commit302ad6228a12fe5cb4c5d332e5bab65ed373bc01 (patch)
tree9e39551b168090a75c28c1d5ba45ef24cdbfc1da /lib/sqlalchemy/sql/selectable.py
parentbf67069d264cba3feed8a48614289d605ed61a55 (diff)
downloadsqlalchemy-302ad6228a12fe5cb4c5d332e5bab65ed373bc01.tar.gz
- Some changes to how the :attr:`.FromClause.c` collection behaves
when presented with duplicate columns. The behavior of emitting a warning and replacing the old column with the same name still remains to some degree; the replacement in particular is to maintain backwards compatibility. However, the replaced column still remains associated with the ``c`` collection now in a collection ``._all_columns``, which is used by constructs such as aliases and unions, to deal with the set of columns in ``c`` more towards what is actually in the list of columns rather than the unique set of key names. This helps with situations where SELECT statements with same-named columns are used in unions and such, so that the union can match the columns up positionally and also there's some chance of :meth:`.FromClause.corresponding_column` still being usable here (it can now return a column that is only in selectable.c._all_columns and not otherwise named). The new collection is underscored as we still need to decide where this list might end up. Theoretically it would become the result of iter(selectable.c), however this would mean that the length of the iteration would no longer match the length of keys(), and that behavior needs to be checked out. fixes #2974 - add a bunch more tests for ColumnCollection
Diffstat (limited to 'lib/sqlalchemy/sql/selectable.py')
-rw-r--r--lib/sqlalchemy/sql/selectable.py15
1 files changed, 8 insertions, 7 deletions
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index 59d6687b5..d59b45fae 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -342,7 +342,7 @@ class FromClause(Selectable):
return column
col, intersect = None, None
target_set = column.proxy_set
- cols = self.c
+ cols = self.c._all_columns
for c in cols:
expanded_proxy_set = set(_expand_cloned(c.proxy_set))
i = target_set.intersection(expanded_proxy_set)
@@ -934,6 +934,7 @@ class Alias(FromClause):
or 'anon'))
self.name = name
+
@property
def description(self):
if util.py3k:
@@ -954,7 +955,7 @@ class Alias(FromClause):
return self.element.is_derived_from(fromclause)
def _populate_column_collection(self):
- for col in self.element.columns:
+ for col in self.element.columns._all_columns:
col._make_proxy(self)
def _refresh_for_new_column(self, column):
@@ -1738,13 +1739,13 @@ class CompoundSelect(GenerativeSelect):
s = _clause_element_as_expr(s)
if not numcols:
- numcols = len(s.c)
- elif len(s.c) != numcols:
+ numcols = len(s.c._all_columns)
+ elif len(s.c._all_columns) != numcols:
raise exc.ArgumentError('All selectables passed to '
'CompoundSelect must have identical numbers of '
'columns; select #%d has %d columns, select '
- '#%d has %d' % (1, len(self.selects[0].c), n
- + 1, len(s.c)))
+ '#%d has %d' % (1, len(self.selects[0].c._all_columns), n
+ + 1, len(s.c._all_columns)))
self.selects.append(s.self_group(self))
@@ -1876,7 +1877,7 @@ class CompoundSelect(GenerativeSelect):
return False
def _populate_column_collection(self):
- for cols in zip(*[s.c for s in self.selects]):
+ for cols in zip(*[s.c._all_columns for s in self.selects]):
# this is a slightly hacky thing - the union exports a
# column that resembles just that of the *first* selectable.