Django + Postgres: "Aktuelle Transaktion wird abgebrochen, Befehle werden bis zum Ende des Transaktionsblocks ignoriert."

74

Ich habe angefangen, an einer Django / Postgres-Site zu arbeiten. Manchmal arbeite ich in manage.py shellund führe versehentlich eine DB-Aktion aus, die zu einem Fehler führt. Dann kann ich überhaupt keine Datenbankaktion ausführen, da bei jeder Datenbankaktion, die ich versuche, folgende Fehlermeldung angezeigt wird:

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

Meine derzeitige Problemumgehung besteht darin, die Shell neu zu starten, aber ich sollte einen Weg finden, dies zu beheben, ohne meine Shell-Sitzung abzubrechen.

(Ich habe dies und das gelesen , aber sie geben keine umsetzbaren Anweisungen, was mit der Shell zu tun ist.)

Ram Rachum
quelle
2
Ich hatte dieses Problem schon einmal und konnte keinen Weg finden, dies zu tun ...
Hoff
1
Mögliches Duplikat davon , das fast die identische akzeptierte Lösung ergibt ...
Cerin

Antworten:

116

Sie können dies versuchen:

from django.db import connection
connection._rollback()

Die ausführlichere Diskussion dieses Problems finden Sie hier

Wsewolod Dyomkin
quelle
5
Diese Lösung funktioniert bei mir nicht. Selbst beim Zurücksetzen der Transaktion kann ich keine Interaktionen mehr mit der Datenbank durchführen. Ich habe eine andere Problemumgehung gefunden, siehe meine Antwort.
Wolkenarchitekt
1
Es gibt auch, connection.close()wenn _rollback es nicht für Sie tut (@ifischer)
Kochfelder
27

das passiert mir manchmal, oft fehlt es

manage.py migrate 

oder

manage.py syncdb

wie auch hier erwähnt

Dies kann auch umgekehrt geschehen, wenn für Ihre models.py eine Schema-Migration ansteht. Mit South müssen Sie das Schema mit aktualisieren.

manage.py schemamigration mymodel --auto
yvess
quelle
3

Ich hatte diesen Fehler, nachdem ich ein Backup in einer völlig leeren Datenbank wiederhergestellt hatte. Es ging nach dem Laufen weg:

./manage syncdb 

Vielleicht fehlten einige interne Modelle auf der Müllkippe ...

Richard
quelle
2

WARNUNG: Der folgende Patch kann möglicherweise dazu führen, dass Transaktionen in der Datenbank offen bleiben (zumindest mit Postgres). Ich bin mir nicht 100% sicher (und wie man das behebt), aber ich empfehle dringend, den folgenden Patch nicht in Produktionsdatenbanken auszuführen.

Da die akzeptierte Antwort meine Probleme nicht löst - sobald ich einen DB-Fehler erhalte, kann ich auch bei einem manuellen Rollback keine neuen DB-Aktionen ausführen - habe ich meine eigene Lösung gefunden.

Wenn ich die Django-Shell ausführe, patche ich Django, um die DB-Verbindung zu schließen, sobald Fehler auftreten. Auf diese Weise muss ich nie daran denken, Transaktionen zurückzusetzen oder die Verbindung zu verwalten.

Dies ist der Code, den ich zu Beginn meiner Django-Shell-Sitzung lade:

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
Wolkenarchitekt
quelle
1
Wenn jemand interessiert ist: Ich habe den Befehl django-extensions shell-plus erweitert, um Dateien beim Start laden zu können, in denen ich neben anderen Sachen auch diesen Patch habe. github.com/ifischer/django-extensions
Wolkenarchitekt
1
Dies wird sicherlich Verbindungen offen lassen, da django.db.close_connectiones sich um eine Funktion handelt, mit der aufgerufen werden muss, ()wenn Sie möchten, dass sie etwas django.db.connection.close()bewirkt ;) Ich mache auch oft eine, die möglicherweise von Alias ​​geprägt ist close_connection, weiß nicht.
Kochfelder
0

Wenn beim Ausführen von migrate(South) ein solcher Fehler auftritt , kann es sein, dass Sie viele Änderungen am Datenbankschema vorgenommen haben und alle gleichzeitig behandeln möchten. Postgres ist ein bisschen böse. Was immer funktioniert, ist, eine große Migration in kleinere Schritte zu unterteilen. Höchstwahrscheinlich verwenden Sie ein Versionskontrollsystem.

  • Ihre aktuelle Version
  • Commit n1
  • Commit n2
  • Commit n3
  • Übernehmen Sie n4 # db Änderungen
  • Commit n5
  • Commit n6
  • Commit n7 # db changse
  • Commit n8
  • Übernehmen Sie n9 # db Änderungen
  • Commit n10

Gehen Sie in der oben beschriebenen Situation wie folgt vor:

  • Checkout-Repository auf "n4", dann synchronisieren und migrieren.
  • Checkout-Repository auf "n7", dann synchronisieren und migrieren.
  • Checkout-Repository auf "n10", dann synchronisieren und migrieren.

Und du bist fertig. :) :)

Es sollte einwandfrei laufen.

Artur Barseghyan
quelle
0

Wenn Sie eine Django-Version vor 1.6 verwenden, sollten Sie das hervorragende xact- Modul von Christophe verwenden .

xact ist ein Rezept für einen vernünftigen Umgang mit Transaktionen in Django-Anwendungen unter PostgreSQL.

Hinweis: Ab Django 1.6 wird die Funktionalität von xact als atomarer Dekorateur in den Django-Kern integriert. Code, der xact verwendet, sollte mit nur einem Suchen und Ersetzen auf atomar migriert werden können. Atomic arbeitet mit anderen Datenbanken als PostgreSQL, ist threadsicher und verfügt über andere nützliche Funktionen. wechsle dorthin, wenn du kannst!

Jeff Sheffield
quelle
0

Ich füge meiner Einstellungsdatei Folgendes hinzu, weil mir die Autocommit-Funktion gefällt, wenn ich "herumspiele", aber nicht möchte, dass sie aktiv ist, wenn meine Site anderweitig ausgeführt wird.

Um Autocommit nur in der Shell zu bekommen, mache ich diesen kleinen Hack:

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

HINWEIS: Dieser zweite Teil ist nur deshalb so, weil ich in PyCharm arbeite, auf dem manage.py nicht direkt ausgeführt wird

Bill Huneke
quelle
0

Ich habe diesen Fehler in Django 1.7 erhalten. Wenn ich in der Dokumentation das lese

Dieses Problem kann im Standardmodus von Django nicht auftreten, und atomic () behandelt es automatisch.

Ich wurde ein bisschen misstrauisch. Die Fehler traten auf, als ich versuchte, Migrationen auszuführen. Es stellte sich heraus, dass einige meiner Modelle hatten my_field = MyField(default=some_function). Diese Funktion als Standard für ein Feld zu haben, funktionierte einwandfrei mit SQLite und MySQL (ich hatte einige Importfehler, aber ich habe es geschafft, dass es funktioniert), obwohl es für PostgresQL nicht zu funktionieren scheint, und es hat die Migrationen bis zu dem Punkt unterbrochen, an dem ich Das Ereignis hat keine hilfreiche Fehlermeldung erhalten, sondern die aus dem Fragentitel.

Eldamir
quelle
Ein bisschen wie ein Nekropost, aber ich treffe genau dieses Problem. Hast du es geschafft, es zu lösen?
Aubricus
1
Kann mich an dieser Stelle nicht erinnern. Mein bester Vorschlag wäre, Migrationsschritte in mehrere Migrationsdateien aufzuteilen und zu prüfen, ob dies hilfreich ist. Schemaänderungen und Datenänderungen können nicht in derselben Migrationsdatei mit postgres sein
Eldamir
Vielen Dank! Es stellt sich heraus, dass Django den Fehler verschluckt hat, den ich endlich per PDF gesehen habe. Aufgrund des Fehlers habe ich das Problem behoben, indem ich der Abhängigkeitsliste einige zusätzliche Elemente hinzugefügt habe.
Aubricus