Подтвердить что ты не робот

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

Im возиться с 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? Как установить/изменить уровень изоляции?

4b9b3361

Ответ 1

Используйте db.set_isolation_level(n), предполагая, что db - ваш объект соединения. Поскольку Federico написал здесь, значение 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

Ответ 2

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

Вы можете изменить этот параметр на уровень изоляции, чтобы автокомментировать с помощью db.set_isolation_level(n), как указал Алекс Мартелли.

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

Ответ 3

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

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