summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/changelog_11.rst8
-rw-r--r--lib/sqlalchemy/orm/session.py6
-rw-r--r--test/orm/test_session.py13
3 files changed, 24 insertions, 3 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst
index 972c1d1df..3fed21b17 100644
--- a/doc/build/changelog/changelog_11.rst
+++ b/doc/build/changelog/changelog_11.rst
@@ -21,6 +21,14 @@
.. changelog::
:version: 1.1.5
+ .. change:: try_finally_for_noautoflush
+ :tags: bug, orm
+
+ The :attr:`.Session.no_autoflush` context manager now ensures that
+ the autoflush flag is reset within a "finally" block, so that if
+ an exception is raised within the block, the state still resets
+ appropriately. Pull request courtesy Emin Arakelian.
+
.. change:: 3878
:tags: bug, sql
:tickets: 3878
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index b39ba1465..cb1ebf013 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -1354,8 +1354,10 @@ class Session(_SessionClassMethods):
"""
autoflush = self.autoflush
self.autoflush = False
- yield self
- self.autoflush = autoflush
+ try:
+ yield self
+ finally:
+ self.autoflush = autoflush
def _autoflush(self):
if self.autoflush and not self._flushing:
diff --git a/test/orm/test_session.py b/test/orm/test_session.py
index 24666d084..5cc8aec20 100644
--- a/test/orm/test_session.py
+++ b/test/orm/test_session.py
@@ -1,5 +1,5 @@
from sqlalchemy.testing import eq_, assert_raises, \
- assert_raises_message, assertions
+ assert_raises_message, assertions, is_true
from sqlalchemy.testing.util import gc_collect
from sqlalchemy.testing import pickleable
from sqlalchemy.util import pickle
@@ -317,6 +317,17 @@ class SessionStateTest(_fixtures.FixtureTest):
assert u in sess.query(User).all()
assert u not in sess.new
+ def test_with_no_autoflush_after_exception(self):
+ sess = Session(autoflush=True)
+
+ assert_raises(
+ ZeroDivisionError,
+ testing.run_as_contextmanager,
+ sess.no_autoflush,
+ lambda obj: 1 / 0
+ )
+
+ is_true(sess.autoflush)
def test_deleted_flag(self):
users, User = self.tables.users, self.classes.User