summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-02-08 21:42:34 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2017-02-08 22:00:28 -0500
commit000e9603065edeb997cfcb492c4063029a931de9 (patch)
treec45740be7141815f1544ebe8a1b3fd8d2ac920ef /lib
parent7db699163bed203d8060f06097e1489eea7ba079 (diff)
downloadsqlalchemy-000e9603065edeb997cfcb492c4063029a931de9.tar.gz
Don't post-SELECT columns w/o a server default/onupdate for eager_defaults
Fixed a major inefficiency in the "eager_defaults" feature whereby an unnecessary SELECT would be emitted for column values where the ORM had explicitly inserted NULL, corresponding to attributes that were unset on the object but did not have any server default specified, as well as expired attributes on update that nevertheless had no server onupdate set up. As these columns are not part of the RETURNING that eager_defaults tries to use, they should not be post-SELECTed either. Change-Id: I0d4f1e9d3d9717d68dcc0592f69456a1f1c36df8 Fixes: #3909
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlalchemy/orm/mapper.py16
-rw-r--r--lib/sqlalchemy/orm/persistence.py8
2 files changed, 22 insertions, 2 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index f45b56ae7..962486d58 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -2042,6 +2042,22 @@ class Mapper(InspectionAttr):
)
@_memoized_configured_property
+ def _server_default_plus_onupdate_propkeys(self):
+ result = set()
+
+ for table, columns in self._cols_by_table.items():
+ for col in columns:
+ if (
+ (
+ col.server_default is not None or
+ col.server_onupdate is not None
+ ) and col in self._columntoproperty
+ ):
+ result.add(self._columntoproperty[col].key)
+
+ return result
+
+ @_memoized_configured_property
def _server_onupdate_default_cols(self):
return dict(
(
diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py
index 8f3e5de58..4d1e38d3f 100644
--- a/lib/sqlalchemy/orm/persistence.py
+++ b/lib/sqlalchemy/orm/persistence.py
@@ -994,8 +994,12 @@ def _finalize_insert_update_commands(base_mapper, uowtransaction, states):
toload_now = []
if base_mapper.eager_defaults:
- toload_now.extend(state._unloaded_non_object)
- elif mapper.version_id_col is not None and \
+ toload_now.extend(
+ state._unloaded_non_object.intersection(
+ mapper._server_default_plus_onupdate_propkeys)
+ )
+
+ if mapper.version_id_col is not None and \
mapper.version_id_generator is False:
if mapper._version_id_prop.key in state.unloaded:
toload_now.extend([mapper._version_id_prop.key])