Как мне выполнять транзакции базы данных с psycopg2/python db api?

Я возлюсь с 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();

Итак, как транзакции работают с psycopg2? Как бы я установить / изменить уровень изоляции?

3 ответа

Использование db.set_isolation_level(n)предполагая db это ваш объект подключения. Как писал здесь Федерико, значение n является:

0 -> autocommit
1 -> read committed
2 -> serialized (but not officially supported by pg)
3 -> serialized

Как задокументировано здесь, 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

BEGIN со стандартным Python DB API всегда неявно. Когда вы начинаете работать с базой данных, драйвер выдает BEGIN и после любого COMMIT или же ROLLBACK другой BEGIN выпущен. API Python DB, совместимый со спецификацией, всегда должен работать таким образом (не только postgresql).

Вы можете изменить эту настройку уровня изоляции для автоматической фиксации с db.set_isolation_level(n) как указал Алекс Мартелли.

Как сказал Тебас, начало неявно, но не выполняется до тех пор, пока не будет выполнен SQL, поэтому, если вы не выполняете SQL, сеанс не находится в транзакции.

Я предпочитаю явно видеть, где мои транзакции:

  • cursor.execute ("BEGIN")
  • cursor.execute ("COMMIT")
Другие вопросы по тегам