]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Ensure session.no_autoflush uses finally
authorplumSemPy <emin@berkekely.edu>
Wed, 4 Jan 2017 17:06:48 +0000 (12:06 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 4 Jan 2017 17:12:52 +0000 (12:12 -0500)
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-Id: Ib19ddf32074b1df82a6a1f1ae14e3a962cd31a5f
Pull-request: https://github.com/zzzeek/sqlalchemy/pull/335

doc/build/changelog/changelog_11.rst
lib/sqlalchemy/orm/session.py
test/orm/test_session.py

index 972c1d1df6a5ee709ed947e9c463f3998abec6d4..3fed21b170f35a4a03119f22e119f8818a41e203 100644 (file)
 .. 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
index b39ba1465a4af72465e1704cc7a281b73b58e837..cb1ebf0130a729a06d6d87badd3e776bd105406a 100644 (file)
@@ -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:
index 24666d084c1bd8fca704e9b9f43daa60efc248f2..5cc8aec2082c151f3c2bc07819254a7225595a34 100644 (file)
@@ -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