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

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

26 голосов
/ 02 августа 2009

Используйте 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
13 голосов
/ 12 августа 2009

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

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

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

6 голосов
/ 04 августа 2009

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

  • cursor.execute ( "BEGIN")
  • cursor.execute ( "COMMIT")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...