The aim of this package is to unify the plethora of existing packages
integrating SQLAlchemy with Zope’s transaction management. As such it seeks
only to provide a data manager and makes no attempt to define a zopeish way
to configure engines.

For WSGI applications, Zope style automatic transaction management is
available with repoze.tm2 (used by Turbogears 2 and other systems).

This package is distributed as a buildout. Using your desired python run:

$ python bootstrap.py
$ ./bin/buildout

This will download the dependent packages and setup the test script, which may
be run with:

$ ./bin/test

or with the standard setuptools test command:

$ ./bin/py setup.py test

To enable testing with your own database set the TEST_DSN environment variable
to your sqlalchemy database dsn. Two-phase commit behaviour may be tested by
setting the TEST_TWOPHASE variable to a non empty string. e.g:

Call the scoped session factory to retrieve a session. You may call this as
many times as you like within a transaction and you will always retrieve the
same session. At present there are no users in the database.

>>> session = Session()
>>> session.query(User).all()
[]

We can now create a new user and commit the changes using Zope’s transaction
machinery, just as Zope’s publisher would.

>>> session.add(User(id=1, name='bob'))
>>> transaction.commit()

Engine level connections are outside the scope of the transaction integration.

By default, zope.sqlalchemy puts sessions in an ‘active’ state when they are
first used. ORM write operations automatically move the session into a
‘changed’ state. This avoids unnecessary database commits. Sometimes it
is necessary to interact with the database directly through SQL. It is not
possible to guess whether such an operation is a read or a write. Therefore we
must manually mark the session as changed when manual SQL statements write
to the DB.

The zope.sqlalchemy.register() function performs the same function as the
ZopeTransactionExtension, except makes use of the newer SQLAlchemy event system
which superseded the extension system as of SQLAlchemy 0.7. Usage is similar:

Add a new function zope.sqlalchemy.register(), which replaces the
direct use of ZopeTransactionExtension to make use
of the newer SQLAlchemy event system to establish instrumentation on
the given Session instance/class/factory. Requires at least
SQLAlchemy 0.7.

Remove redundant session.flush() / session.clear() on savepoint operations.
These were only needed with SQLAlchemy 0.4.x.

SQLAlchemy 0.6.x support. Require SQLAlchemy >= 0.5.1.

Add support for running python setup.py test.

Pull in pysqlite explicitly as a test dependency.

Setup sqlalchemy mappers in test setup and clear them in tear down. This
makes the tests more robust and clears up the global state after. It
caused the tests to fail when other tests in the same run called
clear_mappers.

Remove the session id from the SESSION_STATE just before we de-reference the
session (i.e. all work is already successfuly completed). This fixes cases
where the transaction commit failed but SESSION_STATE was already cleared. In
those cases, the transaction was wedeged as abort would always error. This
happened on PostgreSQL where invalid SQL was used and the error caught.

Call session.flush() unconditionally in tpc_begin.

Change error message on session.commit() to be friendlier to non zope users.