Django + Postgres: «текущая транзакция отменена, команды игнорируются до конца блока транзакции» - PullRequest
71 голосов
/ 13 октября 2011

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

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

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

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

Ответы [ 9 ]

111 голосов
/ 13 октября 2011

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

from django.db import connection
connection._rollback()

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

25 голосов
/ 30 января 2013

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

manage.py migrate 

или

manage.py syncdb

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

это также может произойти и в обратном направлении, если у вас есть схема миграции, ожидающая от вашего models.py. Для юга необходимо обновить схему с помощью.

manage.py schemamigration mymodel --auto
13 голосов
/ 15 февраля 2013

Проверьте это

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

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

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

3 голосов
/ 30 января 2013

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

./manage syncdb 

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

2 голосов
/ 01 февраля 2013

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

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

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

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

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
0 голосов
/ 13 октября 2015

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

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

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

0 голосов
/ 02 апреля 2015

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

Итак, чтобы получить автокоммит только в оболочке, я делаю небольшой взлом:

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

ПРИМЕЧАНИЕ. Эта вторая часть просто потому, что я работаю в PyCharm, который напрямую не запускает manage.py

0 голосов
/ 22 июля 2014

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

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

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

0 голосов
/ 02 ноября 2013

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

  • Текущая версия
  • Commit n1
  • Commit n2
  • Commit n3
  • Фиксация изменений n4 # db
  • Фиксация n5
  • Фиксация n6
  • Фиксация n7 # db changse
  • Фиксация n8
  • Зафиксировать изменения n9 # db
  • Зафиксировать n10

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

  • Извлеките репозиторий в "n4",затем syncdb и миграция.
  • Извлечение хранилища в «n7», затем syncdb и миграция.
  • Извлечение хранилища в «n10», затем syncdb и миграция.

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

Он должен работать без нареканий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...