summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-02-10 23:45:08 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-02-10 23:45:08 +0000
commit8cc35f6d65312b68cb3c663c261f07a6c484f1ad (patch)
tree032b936b84e2f89c9b3d4817924e67e88f7bc516
parentace7e3a4f19f145c390f124f6ea382ca2809bbe3 (diff)
downloadsqlalchemy-8cc35f6d65312b68cb3c663c261f07a6c484f1ad.tar.gz
- added support for py2.5 "with" statement with SessionTransaction [ticket:468]
-rw-r--r--CHANGES1
-rw-r--r--doc/build/content/unitofwork.txt10
-rw-r--r--lib/sqlalchemy/orm/session.py11
3 files changed, 21 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index ae46d9028..fc59d0b85 100644
--- 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
diff --git a/doc/build/content/unitofwork.txt b/doc/build/content/unitofwork.txt
index 9d0e732f9..ddf4bbe47 100644
--- a/doc/build/content/unitofwork.txt
+++ b/doc/build/content/unitofwork.txt
@@ -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.
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index f2a718177..4935b0481 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -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