Django+Postgres: "текущая транзакция прерывается, команды игнорируются до конца блока транзакций"
Я начал работать на сайте Django/Postgres. Иногда я работаю в manage.py shell
, и случайно сделать некоторые действия БД, что приводит к ошибке. Тогда я не могу сделать любой действие базы данных вообще, потому что для любого действия базы данных я пытаюсь сделать, я получаю ошибку:
current transaction is aborted, commands ignored until end of transaction block
мой текущий обходной путь-перезапустить оболочку, но я должен найти способ исправить это, не отказываясь от сеанса оболочки.
(Я читал это и это, но они не дают действенные Инструкции о том, что делать из оболочки.)
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, и он нарушил миграцию до такой степени, что я не получил полезное сообщение об ошибке, а вместо этого из названия вопросов.