web-dev-qa-db-fra.com

Django + Postgres: "la transaction en cours est abandonnée, les commandes sont ignorées jusqu'à la fin du bloc de transaction"

J'ai commencé à travailler sur un site Django/Postgres. Parfois, je travaille dans manage.py Shell et effectue accidentellement une action de base de données qui aboutit à une erreur. Ensuite, je ne peux pas du tout effectuer d'action de base de données [ [] car, pour toute action de base de données que j'essaie de faire, j'obtiens l'erreur

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

Ma solution actuelle consiste à redémarrer le Shell, mais je devrais trouver un moyen de résoudre ce problème sans abandonner ma session Shell.

(J'ai lu ceci et ceci , mais ils ne donnent pas d'instructions exploitables sur ce qu'il faut faire de la part de Shell.)

71
Ram Rachum

Vous pouvez essayer ceci:

from Django.db import connection
connection._rollback()

La discussion plus détaillée de Ce numéro peut être trouvé ici

111
Vsevolod Dyomkin

cela m'arrive parfois, souvent c'est le manque 

manage.py migrate 

ou 

manage.py syncdb

comme mentionné aussi ici

cela peut également se produire dans l'autre sens, si vous avez une migration schemam en attente de votre fichier models.py. Avec south, vous devez mettre à jour le schéma.

manage.py schemamigration mymodel --auto
25
yvess

Vérifie ça

La réponse rapide consiste généralement à activer la validation automatique au niveau de la base de données en ajoutant:

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

Aux paramètres de la base de données.

13
Ignacio Pérez

J'ai eu cette erreur après la restauration d'une sauvegarde sur une base de données totalement vide. Il est parti après avoir couru: 

./manage syncdb 

Peut-être y avait-il des modèles internes manquants dans la décharge ...

3
Richard

AVERTISSEMENT: le correctif ci-dessous peut éventuellement entraîner des transactions laissées à l'état ouvert sur la base de données (au moins avec postgres). Pas tout à fait sûr à ce sujet (et comment le réparer), mais je suggère fortement de ne pas appliquer le correctif ci-dessous sur les bases de données de production.

Comme la réponse acceptée ne résout pas mes problèmes - dès que j'obtiens une erreur de base de données, je ne peux plus effectuer de nouvelle action sur une base de données, même avec une restauration manuelle -, j'ai proposé ma propre solution.

Lorsque j'exécute Django-Shell, je corrige Django pour fermer la connexion à la base de données dès que des erreurs se produisent. De cette façon, je n'ai jamais à penser à annuler des transactions ou à gérer la connexion.

C'est le code que je charge au début de ma session 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
2
ifischer

J'ai eu cette erreur dans Django 1.7. Quand je lis dans la documentation que

Ce problème ne peut pas se produire dans le mode par défaut de Django et dans atomic () le gère automatiquement.

Je suis un peu méfiant. Les erreurs se sont produites lorsque j'ai essayé d'exécuter des migrations. Il s'est avéré que certains de mes modèles avaient my_field = MyField(default=some_function). Avoir cette fonction par défaut pour un champ fonctionnait bien avec sqlite et mysql (j'ai eu quelques erreurs d'importation, mais j'ai réussi à le faire fonctionner), bien que cela ne semble pas fonctionner pour postgresql event n'a pas reçu de message d'erreur utile, mais celui du titre de la question.

0
Eldamir

Si vous utilisez une version de Django antérieure à la version 1.6, vous devriez utiliser l'excellent module xact de Christophe.

xact est une recette pour gérer les transactions de manière judicieuse dans les applications Django sur PostgreSQL.

Note: À partir de Django 1.6, la fonctionnalité de xact sera intégrée au noyau Django en tant que décorateur atomique. Le code qui utilise xact devrait pouvoir être migré vers atomic avec une simple recherche et remplacement. atomic fonctionne sur des bases de données autres que PostgreSQL, est thread-safe et possède d’autres fonctionnalités de Nice; passez à cela quand vous le pourrez!

0
Jeff Sheffield

Si vous obtenez une telle erreur en exécutant migrate (South), il se peut que vous ayez beaucoup de modifications dans le schéma de base de données et que vous souhaitiez les traiter toutes en même temps. Postgres est un peu méchant à ce sujet. Ce qui marche toujours, c’est de diviser une grande migration en petites étapes. Très probablement, vous utilisez un système de contrôle de version.

  • Votre version actuelle
  • Commit n1
  • Commit n2
  • Commit n3
  • Valider les modifications n4 # db
  • Commit n5
  • Commit n6
  • Commit n7 # db changse
  • Commit n8
  • Commit n9 # modifications
  • Commit n10

Alors, ayant la situation décrite ci-dessus, procédez comme suit:

  • Checkout référentiel à "n4", puis syncdb et migrer.
  • Checkout référentiel à "n7", puis syncdb et migrer.
  • Checkout référentiel à "n10", puis syncdb et migrer.

Et tu as fini. :)

Il devrait fonctionner parfaitement.

0
Artur Barseghyan

J'ajoute ce qui suit à mon fichier de paramètres, car j'aime bien la fonctionnalité autocommit lorsque je "joue", mais je ne la veux pas active lorsque mon site est en cours d'exécution.

Donc, pour obtenir l'auto-validation uniquement dans Shell, je fais ce petit bidouillage:

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

NOTE: Cette deuxième partie est juste parce que je travaille dans PyCharm, qui ne lance pas directement manage.py

0
blarobot