如何使用psycopg2/python db api进行数据库事务?

Lee*_*roy 21 python database postgresql

我摆弄了psycopg2,虽然有一个.commit()和.rollback()没有.begin()或者类似的东西来启动一个事务,或者看起来好像?我希望能做到

db.begin() # possible even set the isolation level here
curs = db.cursor()
cursor.execute('select etc... for update')
...
cursor.execute('update ... etc.')
db.commit();
Run Code Online (Sandbox Code Playgroud)

那么,交易如何与psycopg2一起使用?我如何设置/更改隔离级别?

Ale*_*lli 29

使用db.set_isolation_level(n),假设db是您的连接对象.正如费德里科在这里写的那样,意思n是:

0 -> autocommit
1 -> read committed
2 -> serialized (but not officially supported by pg)
3 -> serialized
Run Code Online (Sandbox Code Playgroud)

作为记录在这里,psycopg2.extensions为您提供的通用符号常量:

Setting transaction isolation levels
====================================

psycopg2 connection objects hold informations about the PostgreSQL `transaction
isolation level`_.  The current transaction level can be read from the
`.isolation_level` attribute.  The default isolation level is ``READ
COMMITTED``.  A different isolation level con be set through the
`.set_isolation_level()` method.  The level can be set to one of the following
constants, defined in `psycopg2.extensions`:

`ISOLATION_LEVEL_AUTOCOMMIT`
    No transaction is started when command are issued and no
    `.commit()`/`.rollback()` is required.  Some PostgreSQL command such as
    ``CREATE DATABASE`` can't run into a transaction: to run such command use
    `.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)`.

`ISOLATION_LEVEL_READ_COMMITTED`
    This is the default value.  A new transaction is started at the first
    `.execute()` command on a cursor and at each new `.execute()` after a
    `.commit()` or a `.rollback()`.  The transaction runs in the PostgreSQL
    ``READ COMMITTED`` isolation level.

`ISOLATION_LEVEL_SERIALIZABLE`
    Transactions are run at a ``SERIALIZABLE`` isolation level.


.. _transaction isolation level: 
   http://www.postgresql.org/docs/8.1/static/transaction-iso.html
Run Code Online (Sandbox Code Playgroud)

  • 在我询问之后,Alex 添加了更多内容。它说 READ_COMMITED 是 psycopg2 的默认值 (2认同)

Fer*_*ran 13

BEGIN与Python标准DB API总是隐含的.当您开始使用数据库时,驱动程序会BEGIN在发出任何一个COMMITROLLBACK另一个之后BEGIN发出.符合规范的python DB API应始终以这种方式工作(不仅仅是postgresql).

您可以将此设置的隔离级别更改为自动提交,db.set_isolation_level(n)如Alex Martelli所指出的那样.

正如Tebas所说,开始是隐式的,但在执行SQL之前不会执行,因此如果您不执行任何SQL,则会话不在事务中.

  • 真的吗?我相信在调用commit()或rollback()之后,_not_立即发送另一个BEGIN - 它与下一个execute()隐式发送.在commit()/ rollback()之后,连接处于"空闲"状态而不是"事务中空闲". (2认同)

peu*_*feu 6

我更愿意明确地看到我的交易在哪里:

  • cursor.execute( "BEGIN")
  • cursor.execute( "COMMIT")

  • 是自动提交打开还是关闭?它会混淆Psycopg2或其他数据库模块吗?ODBC的事务管理使用与python DB API类似的方法,我已经看到显式警告*不*使用破坏ODBC接口的SQL事务管理命令(例如http://msdn.microsoft.com/en-us/库/ ms131281.aspx). (2认同)
  • 这是自动提交OFF. (2认同)