summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/loading.py
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2020-01-31 20:00:58 +0000
committerGerrit Code Review <gerrit@bbpush.zzzcomputing.com>2020-01-31 20:00:58 +0000
commit2df647cd7590ae31b542256a5036d2ff49f321aa (patch)
treed03acd7bc2cc63e4f4f77ead7a4fc64ee3c38ec3 /lib/sqlalchemy/orm/loading.py
parent237724d338bf8fd88a24f2bb9dd0c800bda7dbde (diff)
parent10b7937bb9994c365436af5e0c1931b2b07d12b1 (diff)
downloadsqlalchemy-2df647cd7590ae31b542256a5036d2ff49f321aa.tar.gz
Merge "Warn for runid changing in load events; add restore_load_context flag"
Diffstat (limited to 'lib/sqlalchemy/orm/loading.py')
-rw-r--r--lib/sqlalchemy/orm/loading.py30
1 files changed, 29 insertions, 1 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index 218449cdd..617f027d9 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -342,6 +342,18 @@ def _setup_entity_query(
column_collection.append(pd)
+def _warn_for_runid_changed(state):
+ util.warn(
+ "Loading context for %s has changed within a load/refresh "
+ "handler, suggesting a row refresh operation took place. If this "
+ "event handler is expected to be "
+ "emitting row refresh operations within an existing load or refresh "
+ "operation, set restore_load_context=True when establishing the "
+ "listener to ensure the context remains unchanged when the event "
+ "handler completes." % (state_str(state),)
+ )
+
+
def _instance_processor(
mapper,
context,
@@ -580,15 +592,28 @@ def _instance_processor(
)
if isnew:
+ # state.runid should be equal to context.runid / runid
+ # here, however for event checks we are being more conservative
+ # and checking against existing run id
+ # assert state.runid == runid
+
+ existing_runid = state.runid
+
if loaded_instance:
if load_evt:
state.manager.dispatch.load(state, context)
+ if state.runid != existing_runid:
+ _warn_for_runid_changed(state)
if persistent_evt:
- loaded_as_persistent(context.session, state.obj())
+ loaded_as_persistent(context.session, state)
+ if state.runid != existing_runid:
+ _warn_for_runid_changed(state)
elif refresh_evt:
state.manager.dispatch.refresh(
state, context, only_load_props
)
+ if state.runid != runid:
+ _warn_for_runid_changed(state)
if populate_existing or state.modified:
if refresh_state and only_load_props:
@@ -624,7 +649,10 @@ def _instance_processor(
if isnew:
if refresh_evt:
+ existing_runid = state.runid
state.manager.dispatch.refresh(state, context, to_load)
+ if state.runid != existing_runid:
+ _warn_for_runid_changed(state)
state._commit(dict_, to_load)