DatabaseError: текущая транзакция прервана, команды игнорируются до конца блока транзакции? - PullRequest
223 голосов
/ 05 июня 2010

Я получил много ошибок с сообщением:

"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"

после изменения с python-psycopg на python-psycopg2 в качестве движка базы данных проекта Django.

Код остается прежним, просто не знаю, откуда эти ошибки.

Ответы [ 17 ]

159 голосов
/ 05 июня 2010

Это то, что делает postgres, когда запрос выдает ошибку, и вы пытаетесь выполнить другой запрос без предварительного отката транзакции. (Вы можете думать об этом как о функции безопасности, которая не дает вам повредить ваши данные.)

Чтобы исправить это, вам нужно выяснить, где в коде выполняется неверный запрос. Может быть полезно использовать опции log_statement и log_min_error_statement на вашем сервере postgresql.

128 голосов
/ 22 октября 2012

Чтобы избавиться от ошибки, откатите последнюю (ошибочную) транзакцию после того, как вы исправили свой код:

from django.db import transaction
transaction.rollback()

Вы можете использовать try-кроме, чтобы предотвратить возникновение ошибки:

from django.db import transaction, DatabaseError
try:
    a.save()
except DatabaseError:
    transaction.rollback()

См .: Документация Django

50 голосов
/ 10 октября 2011

Итак, я столкнулся с этой же проблемой. Проблема, с которой я столкнулся, заключалась в том, что моя база данных не была правильно синхронизирована. Простые проблемы, кажется, всегда вызывают наибольшее беспокойство ...

Чтобы синхронизировать вашу django db, из каталога вашего приложения в терминале введите:

$ python manage.py syncdb

Изменить: Обратите внимание, что если вы используете django-south, запуск команды '$ python manage.py migrate' также может решить эту проблему.

Удачного кодирования!

30 голосов
/ 03 мая 2012

По моему опыту, эти ошибки происходят следующим образом:

try:
    code_that_executes_bad_query()
    # transaction on DB is now bad
except:
    pass

# transaction on db is still bad
code_that_executes_working_query() # raises transaction error

Во втором запросе нет ничего плохого, но, поскольку обнаружена реальная ошибка, второй запрос вызывает ошибку (гораздо менее информативную).

edit: это происходит только в том случае, если предложение except перехватывает IntegrityError (или любое другое исключение базы данных низкого уровня). Если вы поймаете что-то вроде DoesNotExist, эта ошибка не возникнет, потому что DoesNotExist не повреждает сделка.

Урок здесь - не пытайтесь / кроме / проходите.

17 голосов
/ 08 марта 2018

В Flask вам просто нужно написать:

curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()

P.S. Документация идет здесь https://www.postgresql.org/docs/9.4/static/sql-rollback.html

16 голосов
/ 06 июля 2012

Я думаю, что шаблон, о котором упоминает priestc, с большей вероятностью является обычной причиной этой проблемы при использовании PostgreSQL.

Однако я считаю, что для шаблона есть действительные применения, и я не думаю, что эта проблемапричина всегда избегать этого.Например:

try:
    profile = user.get_profile()
except ObjectDoesNotExist:
    profile = make_default_profile_for_user(user)

do_something_with_profile(profile)

Если вы чувствуете себя нормально с этим шаблоном, но хотите избежать повсеместного использования явного кода обработки транзакций, вы можете захотеть включить режим автоматической фиксации (PostgreSQL 8.2+):https://docs.djangoproject.com/en/dev/ref/databases/#autocommit-mode

DATABASES['default'] = {
    #.. you usual options...
    'OPTIONS': {
        'autocommit': True,
    }
}

Я не уверен, есть ли важные соображения производительности (или любого другого типа).

6 голосов
/ 12 марта 2016

Я столкнулся с похожим поведением при выполнении некорректной транзакции на терминале postgresПосле этого ничего не произошло, так как database находится в состоянии error.Тем не менее, как быстрое решение, если вы можете позволить себе избежать rollback transaction.Следующие сделали трюк для меня:

COMMIT;

6 голосов
/ 05 марта 2014

Если вы получили это, находясь в интерактивной оболочке, и хотите быстро исправить это, сделайте следующее:

from django.db import connection
connection._rollback()

, первоначально увиденный в этот ответ

4 голосов
/ 02 августа 2012

У меня проблема с силимаром. Решением было перенести db (manage.py syncdb или manage.py schemamigration --auto <table name>, если вы используете юг).

2 голосов
/ 29 января 2018

просто используйте откат

Пример кода

try:
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
except:
    cur.execute("rollback")
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
...