]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added support for py2.5 "with" statement with SessionTransaction [ticket:468]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 10 Feb 2007 23:45:08 +0000 (23:45 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 10 Feb 2007 23:45:08 +0000 (23:45 +0000)
CHANGES
doc/build/content/unitofwork.txt
lib/sqlalchemy/orm/session.py

diff --git a/CHANGES b/CHANGES
index ae46d90282cf11d963dca74a95efaa72cdbb626d..fc59d0b85154cfda0daa16abc16e8aa18323f7b5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,7 @@
   items in the cascade [ticket:445]
   - fix to deferred so that load operation doesnt mistakenly occur when only
   PK col attributes are set
+  - added support for py2.5 "with" statement with SessionTransaction [ticket:468]
 - oracle:
   - when returning "rowid" as the ORDER BY column or in use with ROW_NUMBER OVER,
   oracle dialect checks the selectable its being applied to and will switch to 
index 9d0e732f9d57e9cf007d023d30adafa4bb5b9756..ddf4bbe473f65199dcbd35191806db7a57a18218 100644 (file)
@@ -370,6 +370,16 @@ Example usage is as follows:
         raise
     trans.commit()
 
+The SessionTransaction object supports Python 2.5's with statement so that the example above can be written as:
+
+    {python}
+    sess = create_session()
+    with sess.create_transaction():
+        item1 = sess.query(Item).get(1)
+        item2 = sess.query(Item).get(2)
+        item1.foo = 'bar'
+        item2.bar = 'foo'
+
 The `create_transaction()` method creates a new SessionTransaction object but does not declare any connection/transaction resources.  At the point of the first `get()` call, a connection resource is opened off the engine that corresponds to the Item classes' mapper and is stored within the `SessionTransaction` with an open `Transaction`.  When `trans.commit()` is called, the `flush()` method is called on the `Session` and the corresponding update statements are issued to the database within the scope of the transaction already opened; afterwards, the underying Transaction is committed, and connection resources are freed.
 
 `SessionTransaction`, like the `Transaction` off of `Connection` also supports "nested" behavior, and is safe to pass to other functions which then issue their own `begin()`/`commit()` pair; only the outermost `begin()`/`commit()` pair actually affects the transaction, and any call to `rollback()` within a particular call stack will issue a rollback.
index f2a7181774eb9ad14fdd752c2ad8ea73f80c001c..4935b04819f79479f6df0ac17f0f608cc5b106be 100644 (file)
@@ -69,6 +69,15 @@ class SessionTransaction(object):
             if t[2]:
                 t[0].close()
         self.session.transaction = None
+    def __enter__(self):
+        return self
+    def __exit__(self, type, value, traceback):
+        if self.session.transaction is None:
+            return
+        if type is None:
+            self.commit()
+        else:
+            self.rollback()
 
 class Session(object):
     """encapsulates a set of objects being operated upon within an object-relational operation.
@@ -452,4 +461,4 @@ def object_session(obj):
 
 unitofwork.object_session = object_session
 from sqlalchemy.orm import mapper
-mapper.attribute_manager = attribute_manager
\ No newline at end of file
+mapper.attribute_manager = attribute_manager