]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [feature] Added "no_autoflush" context
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Feb 2012 19:34:02 +0000 (14:34 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Feb 2012 19:34:02 +0000 (14:34 -0500)
manager to Session, used with with:
will temporarily disable autoflush.

CHANGES
lib/sqlalchemy/orm/session.py
lib/sqlalchemy/util/__init__.py
lib/sqlalchemy/util/compat.py
test/orm/test_session.py

diff --git a/CHANGES b/CHANGES
index d45f616a00a6e0d7e3b51d1965067052658b2b1c..867ed011860e062b9f3e9c2edaa9bc56d9741f1e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@ CHANGES
 0.7.6
 =====
 - orm
+  - [feature] Added "no_autoflush" context
+    manager to Session, used with with:
+    will temporarily disable autoflush.
+
   - [bug] Fixed bug whereby MappedCollection
     would not get the appropriate collection
     instrumentation if it were only used
index ba6ceaeeca568a94e7e578b80e7651f811a23b04..d01c1598aebcdc2c8424b9bb5660be14181ee1dc 100644 (file)
@@ -978,6 +978,34 @@ class Session(object):
 
         return self._query_cls(entities, self, **kwargs)
 
+    @property
+    @util.contextmanager
+    def no_autoflush(self):
+        """Return a context manager that disables autoflush.
+        
+        e.g.::
+        
+            with session.no_autoflush:
+                
+                some_object = SomeClass()
+                session.add(some_object)
+                # won't autoflush
+                some_object.related_thing = session.query(SomeRelated).first()
+        
+        Operations that proceed within the ``with:`` block
+        will not be subject to flushes occurring upon query
+        access.  This is useful when initializing a series
+        of objects which involve existing database queries,
+        where the uncompleted object should not yet be flushed.
+        
+        New in 0.7.6.
+
+        """
+        autoflush = self.autoflush
+        self.autoflush = False
+        yield self
+        self.autoflush = autoflush
+
     def _autoflush(self):
         if self.autoflush and not self._flushing:
             self.flush()
index 5712940258b97961ff858468d84bbaa2aeadde8d..13914aa7dc5905a3913b4f7d816ef5eaec9fc453 100644 (file)
@@ -7,7 +7,7 @@
 from compat import callable, cmp, reduce, defaultdict, py25_dict, \
     threading, py3k_warning, jython, pypy, win32, set_types, buffer, pickle, \
     update_wrapper, partial, md5_hex, decode_slice, dottedgetter,\
-    parse_qsl, any
+    parse_qsl, any, contextmanager
 
 from _collections import NamedTuple, ImmutableContainer, immutabledict, \
     Properties, OrderedProperties, ImmutableProperties, OrderedDict, \
index 07652f3c6c70814e0d53ab14bcb072c7a5bb14a5..99b92b1e340a9ed80507bafe7dcf92a488797c34 100644 (file)
@@ -56,6 +56,12 @@ def buffer(x):
 buffer = buffer
 # end Py2K
 
+try:
+    from contextlib import contextmanager
+except ImportError:
+    def contextmanager(fn):
+        return fn
+
 try:
     from functools import update_wrapper
 except ImportError:
index ac22455bdf362b48a8d0468c285653727894bc1d..79852c7a4a4fb44910df310b9505d962e8760a1a 100644 (file)
@@ -222,6 +222,23 @@ class SessionTest(_fixtures.FixtureTest):
         eq_(bind.connect().execute("select count(1) from users").scalar(), 1)
         sess.close()
 
+    @testing.requires.python26
+    def test_with_no_autoflush(self):
+        User, users = self.classes.User, self.tables.users
+
+        mapper(User, users)
+        sess = Session()
+
+        u = User()
+        u.name = 'ed'
+        sess.add(u)
+        def go(obj):
+            assert u not in sess.query(User).all()
+        testing.run_as_contextmanager(sess.no_autoflush, go)
+        assert u in sess.new
+        assert u in sess.query(User).all()
+        assert u not in sess.new
+
     def test_make_transient(self):
         users, User = self.tables.users, self.classes.User