From 179dce0022c4fb58d83b5e815401d28489878c0e Mon Sep 17 00:00:00 2001 From: Cristian Sabaila Date: Wed, 3 Nov 2021 00:16:49 +0200 Subject: [PATCH] Fixed issue in MySQL :meth:`.mysql.Insert.on_duplicate_key_update` construct where referencing a column within a composed expression would render the ``VALUES`` keyword to the column name of the argument. --- lib/sqlalchemy/dialects/mysql/base.py | 2 +- test/dialect/mysql/test_compiler.py | 4 ++-- test/dialect/mysql/test_on_duplicate.py | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 4827df12f1..684f35c5f8 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1302,7 +1302,7 @@ class MySQLCompiler(compiler.SQLCompiler): and obj.table is on_duplicate.inserted_alias ): obj = literal_column( - "VALUES(" + self.preparer.quote(column.name) + ")" + "VALUES(" + self.preparer.quote(obj.name) + ")" ) return obj else: diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py index 708039f943..a6ead333fa 100644 --- a/test/dialect/mysql/test_compiler.py +++ b/test/dialect/mysql/test_compiler.py @@ -1110,12 +1110,12 @@ class InsertOnDuplicateTest(fixtures.TestBase, AssertsCompiledSQL): ) stmt = stmt.on_duplicate_key_update( bar=func.coalesce(stmt.inserted.bar), - baz=stmt.inserted.baz + "some literal", + baz=stmt.inserted.baz + "some literal" + stmt.inserted.bar, ) expected_sql = ( "INSERT INTO foos (id, bar) VALUES (%s, %s), (%s, %s) ON " "DUPLICATE KEY UPDATE bar = coalesce(VALUES(bar)), " - "baz = (concat(VALUES(baz), %s))" + "baz = (concat(VALUES(bar), %s, VALUES(baz)))" ) self.assert_compile( stmt, diff --git a/test/dialect/mysql/test_on_duplicate.py b/test/dialect/mysql/test_on_duplicate.py index 65d5b8364e..4c8307d907 100644 --- a/test/dialect/mysql/test_on_duplicate.py +++ b/test/dialect/mysql/test_on_duplicate.py @@ -100,13 +100,18 @@ class OnDuplicateTest(fixtures.TablesTest): conn.execute(insert(foos).values(dict(id=1, bar="b", baz="bz"))) stmt = insert(foos).values([dict(id=1, bar="ab"), dict(id=2, bar="b")]) stmt = stmt.on_duplicate_key_update( - bar=func.concat(stmt.inserted.bar, "_foo") + bar=func.concat(stmt.inserted.bar, "_foo"), + baz=func.concat(stmt.inserted.bar, foos.baz), ) result = conn.execute(stmt) eq_(result.inserted_primary_key, (None,)) eq_( conn.execute(foos.select().where(foos.c.id == 1)).fetchall(), - [(1, "ab_foo", "bz", False)], + [(1, "ab_foo", "ab_bz", False)], + ) + eq_( + conn.execute(foos.select().where(foos.c.id == 1)).fetchall(), + [(2, "b_foo", "b_bz", False)], ) def test_on_duplicate_key_update_preserve_order(self, connection): -- 2.47.3