diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-02-25 14:34:02 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-02-25 14:34:02 -0500 |
| commit | deb7e76a42fac9995174f30baa365b4d03ddee3c (patch) | |
| tree | a0f765595d9df4231eda13dd78bef21c94df43bd | |
| parent | abe6c0f08a49859d8a2c36f4011e6f81ebf7ecb2 (diff) | |
| download | sqlalchemy-deb7e76a42fac9995174f30baa365b4d03ddee3c.tar.gz | |
- [feature] Added "no_autoflush" context
manager to Session, used with with:
will temporarily disable autoflush.
| -rw-r--r-- | CHANGES | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/session.py | 28 | ||||
| -rw-r--r-- | lib/sqlalchemy/util/__init__.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/util/compat.py | 6 | ||||
| -rw-r--r-- | test/orm/test_session.py | 17 |
5 files changed, 56 insertions, 1 deletions
@@ -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 diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index ba6ceaeec..d01c1598a 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -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() diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 571294025..13914aa7d 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -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, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 07652f3c6..99b92b1e3 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -57,6 +57,12 @@ buffer = buffer # end Py2K try: + from contextlib import contextmanager +except ImportError: + def contextmanager(fn): + return fn + +try: from functools import update_wrapper except ImportError: def update_wrapper(wrapper, wrapped, diff --git a/test/orm/test_session.py b/test/orm/test_session.py index ac22455bd..79852c7a4 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -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 |
