summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-02-26 15:45:52 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-02-26 15:45:52 -0500
commit6aeec027a0fb33348bdb8ec5b448044a67eff7c5 (patch)
treef7f1528f6827e1259678904765db296fdd016324
parent302ad6228a12fe5cb4c5d332e5bab65ed373bc01 (diff)
downloadsqlalchemy-6aeec027a0fb33348bdb8ec5b448044a67eff7c5.tar.gz
- Adjusted the logic which applies names to the .c collection when
a no-name :class:`.BindParameter` is received, e.g. via :func:`.sql.literal` or similar; the "key" of the bind param is used as the key within .c. rather than the rendered name. Since these binds have "anonymous" names in any case, this allows individual bound parameters to have their own name within a selectable if they are otherwise unlabeled. fixes #2974
-rw-r--r--doc/build/changelog/changelog_09.rst11
-rw-r--r--lib/sqlalchemy/sql/elements.py15
-rw-r--r--test/sql/test_compiler.py10
-rw-r--r--test/sql/test_update.py2
4 files changed, 29 insertions, 9 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index 9a1ff9f27..a5c22aefc 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -18,6 +18,17 @@
:tags: bug, sql
:tickets: 2974
+ Adjusted the logic which applies names to the .c collection when
+ a no-name :class:`.BindParameter` is received, e.g. via :func:`.sql.literal`
+ or similar; the "key" of the bind param is used as the key within
+ .c. rather than the rendered name. Since these binds have "anonymous"
+ names in any case, this allows individual bound parameters to
+ have their own name within a selectable if they are otherwise unlabeled.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 2974
+
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
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index 1b49a7cd1..f2ce0619c 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -588,7 +588,7 @@ class ColumnElement(ClauseElement, operators.ColumnOperators):
primary_key = False
foreign_keys = []
_label = None
- _key_label = None
+ _key_label = key = None
_alt_names = ()
def self_group(self, against=None):
@@ -681,10 +681,14 @@ class ColumnElement(ClauseElement, operators.ColumnOperators):
"""
if name is None:
name = self.anon_label
- try:
- key = str(self)
- except exc.UnsupportedCompilationError:
- key = self.anon_label
+ if self.key:
+ key = self.key
+ else:
+ try:
+ key = str(self)
+ except exc.UnsupportedCompilationError:
+ key = self.anon_label
+
else:
key = name
co = ColumnClause(
@@ -755,7 +759,6 @@ class ColumnElement(ClauseElement, operators.ColumnOperators):
'name', 'anon')))
-
class BindParameter(ColumnElement):
"""Represent a "bound expression".
diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py
index 25aa78b03..b1c807df6 100644
--- a/test/sql/test_compiler.py
+++ b/test/sql/test_compiler.py
@@ -2082,6 +2082,10 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
)
def test_naming(self):
+ # TODO: the part where we check c.keys() are not "compile" tests, they
+ # belong probably in test_selectable, or some broken up
+ # version of that suite
+
f1 = func.hoho(table1.c.name)
s1 = select([table1.c.myid, table1.c.myid.label('foobar'),
f1,
@@ -2098,7 +2102,8 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
exprs = (
table1.c.myid == 12,
func.hoho(table1.c.myid),
- cast(table1.c.name, Numeric)
+ cast(table1.c.name, Numeric),
+ literal('x'),
)
for col, key, expr, label in (
(table1.c.name, 'name', 'mytable.name', None),
@@ -2108,7 +2113,8 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
'CAST(mytable.name AS NUMERIC)', 'anon_1'),
(t1.c.col1, 'col1', 'mytable.col1', None),
(column('some wacky thing'), 'some wacky thing',
- '"some wacky thing"', '')
+ '"some wacky thing"', ''),
+ (exprs[3], exprs[3].key, ":param_1", "anon_1")
):
if getattr(col, 'table', None) is not None:
t = col.table
diff --git a/test/sql/test_update.py b/test/sql/test_update.py
index 10306372b..a1b64d862 100644
--- a/test/sql/test_update.py
+++ b/test/sql/test_update.py
@@ -203,7 +203,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
"""
table1 = self.tables.mytable
expr = func.foo(table1.c.myid)
- assert not hasattr(expr, 'key')
+ eq_(expr.key, None)
self.assert_compile(table1.update().values({expr: 'bar'}),
'UPDATE mytable SET foo(myid)=:param_1')