From: Mike Bayer Date: Wed, 26 Feb 2014 20:45:52 +0000 (-0500) Subject: - Adjusted the logic which applies names to the .c collection when X-Git-Tag: rel_0_9_4~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6aeec027a0fb33348bdb8ec5b448044a67eff7c5;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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 --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 9a1ff9f277..a5c22aefc9 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,17 @@ .. changelog:: :version: 0.9.4 + .. change:: + :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 diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 1b49a7cd1c..f2ce0619c7 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 25aa78b035..b1c807df69 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 10306372b2..a1b64d8628 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')