From: Mike Bayer Date: Tue, 6 Dec 2011 17:41:01 +0000 (-0500) Subject: add BEGIN workaround to pysqlite docs, [ticket:2219] X-Git-Tag: rel_0_7_4~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bd4c1dd38c503df467e9297dfc6dcfa35b9df9c3;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git add BEGIN workaround to pysqlite docs, [ticket:2219] --- diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index f0c9a0ccaa..9d5e070b3d 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -46,10 +46,12 @@ to the Table construct:: Transaction Isolation Level --------------------------- -:func:`create_engine` accepts an ``isolation_level`` parameter which results in +:func:`.create_engine` accepts an ``isolation_level`` parameter which results in the command ``PRAGMA read_uncommitted `` being invoked for every new connection. Valid values for this parameter are ``SERIALIZABLE`` and ``READ UNCOMMITTED`` corresponding to a value of 0 and 1, respectively. +See the section :ref:`pysqlite_serializable` for an important workaround +when using serializable isolation with Pysqlite. """ diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index ad8d5c6f9f..63832b8f37 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -182,6 +182,31 @@ require unicode, however, so that non-``unicode`` values passed inadvertently will emit a warning. Pysqlite will emit an error if a non-``unicode`` string is passed containing non-ASCII characters. +.. _pysqlite_serializable: + +Serializable Transaction Isolation +---------------------------------- + +The pysqlite DBAPI driver has a long-standing bug in which transactional +state is not begun until the first DML statement, that is INSERT, UPDATE +or DELETE, is emitted. A SELECT statement will not cause transactional +state to begin. While this mode of usage is fine for typical situations +and has the advantage that the SQLite database file is not prematurely +locked, it breaks serializable transaction isolation, which requires +that the database file be locked upon any SQL being emitted. + +To work around this issue, the ``BEGIN`` keyword can be emitted +at the start of each transaction. The following recipe establishes +a :meth:`.ConnectionEvents.begin` handler to achieve this:: + + from sqlalchemy import create_engine, event + + engine = create_engine("sqlite:///myfile.db", isolation_level='SERIALIZABLE') + + @event.listens_for(engine, "begin") + def do_begin(conn): + conn.execute("BEGIN") + """ from sqlalchemy.dialects.sqlite.base import SQLiteDialect, DATETIME, DATE