From c2aa6374f3965c28aa2d56cbddf6dab3e1de18a2 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 8 Feb 2022 10:12:33 -0500 Subject: Accommodate escaped_bind_names for defaults/insert params Fixed issue in Oracle dialect where using a column name that requires quoting when written as a bound parameter, such as ``"_id"``, would not correctly track a Python generated default value due to the bound-parameter rewriting missing this value, causing an Oracle error to be raised. Fixes: #7676 Change-Id: I5a54426d24f2f9b336e3597d5595fb3e031aad97 --- lib/sqlalchemy/sql/compiler.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'lib/sqlalchemy/sql/compiler.py') diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 8a3f26425..9cf4d8397 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1254,16 +1254,29 @@ class SQLCompiler(Compiled): self._result_columns ) + @util.memoized_property + def _within_exec_param_key_getter(self): + getter = self._key_getters_for_crud_column[2] + if self.escaped_bind_names: + + def _get(obj): + key = getter(obj) + return self.escaped_bind_names.get(key, key) + + return _get + else: + return getter + @util.memoized_property @util.preload_module("sqlalchemy.engine.result") def _inserted_primary_key_from_lastrowid_getter(self): result = util.preloaded.engine_result - key_getter = self._key_getters_for_crud_column[2] + param_key_getter = self._within_exec_param_key_getter table = self.statement.table getters = [ - (operator.methodcaller("get", key_getter(col), None), col) + (operator.methodcaller("get", param_key_getter(col), None), col) for col in table.primary_key ] @@ -1279,6 +1292,12 @@ class SQLCompiler(Compiled): row_fn = result.result_tuple([col.key for col in table.primary_key]) def get(lastrowid, parameters): + """given cursor.lastrowid value and the parameters used for INSERT, + return a "row" that represents the primary key, either by + using the "lastrowid" or by extracting values from the parameters + that were sent along with the INSERT. + + """ if proc is not None: lastrowid = proc(lastrowid) @@ -1297,7 +1316,7 @@ class SQLCompiler(Compiled): def _inserted_primary_key_from_returning_getter(self): result = util.preloaded.engine_result - key_getter = self._key_getters_for_crud_column[2] + param_key_getter = self._within_exec_param_key_getter table = self.statement.table ret = {col: idx for idx, col in enumerate(self.returning)} @@ -1305,7 +1324,10 @@ class SQLCompiler(Compiled): getters = [ (operator.itemgetter(ret[col]), True) if col in ret - else (operator.methodcaller("get", key_getter(col), None), False) + else ( + operator.methodcaller("get", param_key_getter(col), None), + False, + ) for col in table.primary_key ] -- cgit v1.2.1