diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-03-15 10:15:12 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2017-03-15 10:40:30 -0400 |
commit | 7b056709c0f8a37744d18f37d40f94fa30c50c71 (patch) | |
tree | 80570e7cffab0b5553954760fa5e608f5820c535 | |
parent | 0a35ccc6bd1acaa91f32c8e0140000b19ae85e14 (diff) | |
download | sqlalchemy-7b056709c0f8a37744d18f37d40f94fa30c50c71.tar.gz |
Consult compiled paramstyle on execute_compiled
Fixed bug where in the unusual case of passing a
:class:`.Compiled` object directly to :meth:`.Connection.execute`,
the dialect with which the :class:`.Compiled` object were generated
was not consulted for the paramstyle of the string statement, instead
assuming it would match the dialect-level paramstyle, causing
mismatches to occur.
Change-Id: I114e4db2183fbb75bb7c0b0641f5a161855696ee
Fixes: #3938
-rw-r--r-- | doc/build/changelog/changelog_12.rst | 11 | ||||
-rw-r--r-- | lib/sqlalchemy/engine/default.py | 2 | ||||
-rw-r--r-- | test/engine/test_execute.py | 30 |
3 files changed, 42 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_12.rst b/doc/build/changelog/changelog_12.rst index 7e6c406da..f2646fdf1 100644 --- a/doc/build/changelog/changelog_12.rst +++ b/doc/build/changelog/changelog_12.rst @@ -13,6 +13,17 @@ .. changelog:: :version: 1.2.0b1 + .. change:: 3938 + :tags: bug, engine + :tickets: 3938 + + Fixed bug where in the unusual case of passing a + :class:`.Compiled` object directly to :meth:`.Connection.execute`, + the dialect with which the :class:`.Compiled` object were generated + was not consulted for the paramstyle of the string statement, instead + assuming it would match the dialect-level paramstyle, causing + mismatches to occur. + .. change:: 3918 :tags: bug, ext :tickets: 3918 diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index b8c2d2845..3968663fb 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -627,7 +627,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): # into a dict or list to be sent to the DBAPI's # execute() or executemany() method. parameters = [] - if dialect.positional: + if compiled.positional: for compiled_params in self.compiled_parameters: param = [] for key in self.compiled.positiontup: diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index 32834f950..54a85bf9f 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -19,6 +19,7 @@ from sqlalchemy.engine import result as _result, default from sqlalchemy.engine.base import Engine from sqlalchemy.testing import fixtures from sqlalchemy.testing.mock import Mock, call, patch +from sqlalchemy.testing import mock from contextlib import contextmanager from sqlalchemy.util import nested from sqlalchemy.testing.assertsql import CompiledSQL @@ -433,6 +434,35 @@ class ExecuteTest(fixtures.TestBase): values(user_name=bindparam('name', None)), []) eq_(testing.db.execute(users_autoinc.select()).fetchall(), [(1, None)]) + @testing.only_on("sqlite") + def test_execute_compiled_favors_compiled_paramstyle(self): + with patch.object(testing.db.dialect, "do_execute") as do_exec: + stmt = users.update().values(user_id=1, user_name='foo') + + d1 = default.DefaultDialect(paramstyle="format") + d2 = default.DefaultDialect(paramstyle="pyformat") + + testing.db.execute(stmt.compile(dialect=d1)) + testing.db.execute(stmt.compile(dialect=d2)) + + eq_( + do_exec.mock_calls, [ + call( + mock.ANY, + "UPDATE users SET user_id=%s, user_name=%s", + (1, 'foo'), + mock.ANY + ), + call( + mock.ANY, + "UPDATE users SET user_id=%(user_id)s, " + "user_name=%(user_name)s", + {'user_name': 'foo', 'user_id': 1}, + mock.ANY + ) + ] + ) + @testing.requires.ad_hoc_engines def test_engine_level_options(self): eng = engines.testing_engine(options={'execution_options': |