summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/session.py30
-rw-r--r--lib/sqlalchemy/orm/unitofwork.py15
2 files changed, 42 insertions, 3 deletions
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index 1df9d45ca..dcbd6ba7e 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -555,6 +555,7 @@ class Session(_SessionClassMethods):
self.bind = bind
self.__binds = {}
self._flushing = False
+ self._warn_on_events = False
self.transaction = None
self.hash_key = _new_sessionid()
self.autoflush = autoflush
@@ -1323,7 +1324,7 @@ class Session(_SessionClassMethods):
self._deleted.pop(state, None)
state.deleted = True
- def add(self, instance):
+ def add(self, instance, _warn=True):
"""Place an object in the ``Session``.
Its state will be persisted to the database on the next flush
@@ -1333,6 +1334,9 @@ class Session(_SessionClassMethods):
is ``expunge()``.
"""
+ if _warn and self._warn_on_events:
+ self._flush_warning("Session.add()")
+
try:
state = attributes.instance_state(instance)
except exc.NO_STATE:
@@ -1343,8 +1347,11 @@ class Session(_SessionClassMethods):
def add_all(self, instances):
"""Add the given collection of instances to this ``Session``."""
+ if self._warn_on_events:
+ self._flush_warning("Session.add_all()")
+
for instance in instances:
- self.add(instance)
+ self.add(instance, _warn=False)
def _save_or_update_state(self, state):
self._save_or_update_impl(state)
@@ -1362,6 +1369,9 @@ class Session(_SessionClassMethods):
The database delete operation occurs upon ``flush()``.
"""
+ if self._warn_on_events:
+ self._flush_warning("Session.delete()")
+
try:
state = attributes.instance_state(instance)
except exc.NO_STATE:
@@ -1436,6 +1446,9 @@ class Session(_SessionClassMethods):
"""
+ if self._warn_on_events:
+ self._flush_warning("Session.merge()")
+
_recursive = {}
if load:
@@ -1744,6 +1757,13 @@ class Session(_SessionClassMethods):
finally:
self._flushing = False
+ def _flush_warning(self, method):
+ util.warn("Usage of the '%s' operation is not currently supported "
+ "within the execution stage of the flush process. "
+ "Results may not be consistent. Consider using alternative "
+ "event listeners or connection-level operations instead."
+ % method)
+
def _is_clean(self):
return not self.identity_map.check_modified() and \
not self._deleted and \
@@ -1811,7 +1831,11 @@ class Session(_SessionClassMethods):
flush_context.transaction = transaction = self.begin(
subtransactions=True)
try:
- flush_context.execute()
+ self._warn_on_events = True
+ try:
+ flush_context.execute()
+ finally:
+ self._warn_on_events = False
self.dispatch.after_flush(self, flush_context)
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py
index 5fb7a55e5..1cba58321 100644
--- a/lib/sqlalchemy/orm/unitofwork.py
+++ b/lib/sqlalchemy/orm/unitofwork.py
@@ -34,6 +34,9 @@ def track_cascade_events(descriptor, prop):
sess = sessionlib._state_session(state)
if sess:
+ if sess._warn_on_events:
+ sess._flush_warning("collection append")
+
prop = state.manager.mapper._props[key]
item_state = attributes.instance_state(item)
if prop.cascade.save_update and \
@@ -48,7 +51,15 @@ def track_cascade_events(descriptor, prop):
sess = sessionlib._state_session(state)
if sess:
+
prop = state.manager.mapper._props[key]
+
+ if sess._warn_on_events:
+ sess._flush_warning(
+ "collection remove"
+ if prop.uselist
+ else "related attribute delete")
+
# expunge pending orphans
item_state = attributes.instance_state(item)
if prop.cascade.delete_orphan and \
@@ -64,6 +75,10 @@ def track_cascade_events(descriptor, prop):
sess = sessionlib._state_session(state)
if sess:
+
+ if sess._warn_on_events:
+ sess._flush_warning("related attribute set")
+
prop = state.manager.mapper._props[key]
if newvalue is not None:
newvalue_state = attributes.instance_state(newvalue)