summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/mssql
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2019-10-05 00:05:33 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2019-10-05 00:05:33 +0000
commitc6abd4766abb0396c9bf532d81d16226b970a35a (patch)
tree5ac87ae9557926cceacc2a58ece4b43053a6798f /lib/sqlalchemy/dialects/mssql
parentb73c191903d5f23b02188474f6a8a1b877988a40 (diff)
parent485216dea6d7a5814d200b4f14b8a363ed0f8caa (diff)
downloadsqlalchemy-c6abd4766abb0396c9bf532d81d16226b970a35a.tar.gz
Merge "Deprecate textual column matching in Row"
Diffstat (limited to 'lib/sqlalchemy/dialects/mssql')
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py19
1 files changed, 18 insertions, 1 deletions
diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py
index d4d303d5d..94c2cbe6d 100644
--- a/lib/sqlalchemy/dialects/mssql/base.py
+++ b/lib/sqlalchemy/dialects/mssql/base.py
@@ -1783,6 +1783,11 @@ class MSSQLCompiler(compiler.SQLCompiler):
return super(MSSQLCompiler, self).visit_binary(binary, **kwargs)
def returning_clause(self, stmt, returning_cols):
+ # SQL server returning clause requires that the columns refer to
+ # the virtual table names "inserted" or "deleted". Here, we make
+ # a simple alias of our table with that name, and then adapt the
+ # columns we have from the list of RETURNING columns to that new name
+ # so that they render as "inserted.<colname>" / "deleted.<colname>".
if self.isinsert or self.isupdate:
target = stmt.table.alias("inserted")
@@ -1791,9 +1796,21 @@ class MSSQLCompiler(compiler.SQLCompiler):
adapter = sql_util.ClauseAdapter(target)
+ # adapter.traverse() takes a column from our target table and returns
+ # the one that is linked to the "inserted" / "deleted" tables. So in
+ # order to retrieve these values back from the result (e.g. like
+ # row[column]), tell the compiler to also add the original unadapted
+ # column to the result map. Before #4877, these were (unknowingly)
+ # falling back using string name matching in the result set which
+ # necessarily used an expensive KeyError in order to match.
+
columns = [
self._label_select_column(
- None, adapter.traverse(c), True, False, {}
+ None,
+ adapter.traverse(c),
+ True,
+ False,
+ {"result_map_targets": (c,)},
)
for c in expression._select_iterables(returning_cols)
]