Django+Postgres: "текущая транзакция прерывается, команды игнорируются до конца блока транзакций"


Я начал работать на сайте Django/Postgres. Иногда я работаю в manage.py shell, и случайно сделать некоторые действия БД, что приводит к ошибке. Тогда я не могу сделать любой действие базы данных вообще, потому что для любого действия базы данных я пытаюсь сделать, я получаю ошибку:

current transaction is aborted, commands ignored until end of transaction block

мой текущий обходной путь-перезапустить оболочку, но я должен найти способ исправить это, не отказываясь от сеанса оболочки.

(Я читал это и это, но они не дают действенные Инструкции о том, что делать из оболочки.)

9 70

9 ответов:

вы можете попробовать это:

from django.db import connection
connection._rollback()

более подробное обсуждение этот вопрос можно найти здесь

это случается со мной иногда, чаще это отсутствует

manage.py migrate 

или

manage.py syncdb

как уже упоминалось здесь

Это также может произойти наоборот, если у вас есть schemamigration в ожидании от вашего models.py. с юга вам нужно обновить схему С.

manage.py schemamigration mymodel --auto

проверить это

быстрый ответ обычно для включения автоматической фиксации на уровне базы данных, добавив:

'OPTIONS': {'autocommit': True,}

настройки базы данных.

У меня была эта ошибка после восстановления резервной копии в полностью пустую БД. Он ушел после бега:

./manage syncdb 

возможно, в дампе отсутствовали некоторые внутренние модели...

предупреждение: патч ниже может привести к тому, что транзакции останутся в открытом состоянии в БД (по крайней мере, с postgres). Не на 100% уверен, что (и как исправить), но я настоятельно рекомендую не делать патч ниже на производственных базах данных.

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

когда я запускаю Django-shell, я исправляю Django, чтобы закрыть соединение с БД, как только возникнут какие-либо ошибки. Таким образом, мне никогда не придется думать об откате транзакций или обработке соединения.

Это код, который я загружаю в начале моего Django-shell-session:

from django import db
from django.db.backends.util import CursorDebugWrapper
old_execute = CursorDebugWrapper.execute
old_execute_many = CursorDebugWrapper.executemany

def execute_wrapper(*args, **kwargs):
    try:
        old_execute(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

def execute_many_wrapper(*args, **kwargs):
    try:
        old_execute_many(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection

CursorDebugWrapper.execute = execute_wrapper
CursorDebugWrapper.executemany = execute_many_wrapper

Если вы случайно получаете такую ошибку при запуске migrate (Юг), это может быть, что у вас есть много изменений в схеме базы данных и хотите обрабатывать их все сразу. Постгрес немного противный на этом. То, что всегда работает, - это разбить одну большую миграцию на более мелкие шаги. Скорее всего, вы используете систему контроля версий.

  • ваша текущая версия
  • Commit n1
  • Commit n2
  • Commit n3
  • Commit n4 # db изменения
  • совершить n5
  • Commit n6
  • Commit n7 # db changse
  • Commit n8
  • Commit N9 # db changes
  • Commit n10

Итак, имея описанную выше ситуацию, сделайте следующее:

  • проверка репозитория на "n4", затем syncdb и миграция.
  • проверка репозитория на "n7", затем syncdb и миграция.
  • проверка репозитория на "n10" , затем syncdb и мигрировать.

и вы сделали. :)

Он должен работать безупречно.

Если вы используете версию django до 1.6, то вы должны использовать Кристофа отлично xact модуль.

xact это рецепт для разумной обработки транзакций в приложениях Django на PostgreSQL.

Примечание: начиная с Django 1.6, функциональность xact будет объединена в ядро Django в качестве атомарного декоратора. Код, который использует xact, должен быть перенесен в atomic только с помощью функции поиска и замены. атомное строительство в базах данных, отличных от PostgreSQL, является потокобезопасным и имеет другие приятные функции; переключитесь на него, когда сможете!

Я добавляю следующее в свой файл настроек, потому что мне нравится функция автоматической фиксации, когда я "играю", но не хочу, чтобы она была активна, когда мой сайт работает иначе.

поэтому, чтобы получить autocommit только в оболочке, я делаю этот маленький хак:

import sys
if 'shell' in sys.argv or sys.argv[0].endswith('pydevconsole.py'):
    DATABASES['default']['OPTIONS']['autocommit'] = True

Примечание: эта вторая часть просто потому, что я работаю в PyCharm, который не работает напрямую manage.py

Я получил эту ошибку в Django 1.7. Когда я читаю в документация это

эта проблема не может возникнуть в режиме Django по умолчанию и atomic() обрабатывает его автоматически.

У меня возникли некоторые подозрения. Ошибки произошли, когда я попытался запустить миграции. Оказалось, что некоторые из моих моделей было my_field = MyField(default=some_function). Наличие этой функции по умолчанию для поля хорошо работало с sqlite и mysql (у меня были некоторые ошибки импорта, но мне удалось make it work), хотя он, похоже, не работает для postgresql, и он нарушил миграцию до такой степени, что я не получил полезное сообщение об ошибке, а вместо этого из названия вопросов.