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, и он нарушил миграцию до такой степени, что я не получил полезное сообщение об ошибке, а вместо этого из названия вопросов.