Postgres: cursor.execute(COMMIT) и connection.commit()

Я использую сервер postgres 9.2 и клиент python, использующий psycopg 2.5.

Я провел несколько тестов, потому что в моих лог-файлах появилось много записей WARNING: there is no transaction in progress.

У меня есть код, который можно упростить до следующего:

import psycopg2

connection = psycopg2.connect(...)
with connection.cursor() as cursor:
    # Multiple insert statements
    cursor.execute("INSERT INTO ...")

    cursor.execute("COMMIT")

Я обнаружил, что если я сделаю следующее, как только будет запущен первый COMMIT (я повторно использую одно и то же соединение, поэтому приведенный выше код запускается несколько раз), каждый последующий оператор мгновенно фиксируется. Однако, если я вместо этого запускаю connection.commit(), он работает так, как ожидалось (операторы фиксации, сделанные до сих пор, будущие операторы не будут зафиксированы автоматически).

Это ошибка или есть какое-то тонкое различие, которое я где-то пропустил в том, как это работает? Это проблема postgres или что-то связанное с внутренностями psycopg2?

Заранее спасибо!


person Christian P.    schedule 06.05.2014    source источник


Ответы (1)


Да, есть не такое тонкое различие (задокументированное как в DBAPI PEP, так и в документации psycopg). Все адаптеры Python, совместимые с DBAPI, неявно запускают транзакцию при выполнении первого оператора SQL через соединение. Тогда вам не следует выполнять откат/фиксацию напрямую, а вместо этого использовать методы, доступные для объекта connection.

Если вы хотите выполнить собственное управление транзакциями, просто переведите соединение в режим автоматической фиксации, а затем отправьте свой собственный BEGIN, за которым следуют другие операторы и закончите обычным COMMIT или ROLLBACK.

person fog    schedule 06.05.2014