Django + Postgres: “la transaction en cours est annulé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 le manage.py shell et effectue accidentellement une action de la firebase database manage.py shell une erreur. Je suis alors incapable de faire une action de base de données car pour toute action de firebase database que j’essaie de faire, j’obtiens l’erreur suivante:

 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 cela , mais ils ne donnent pas d’instructions pratiques sur ce qu’il faut faire du shell.)

    Vous pouvez essayer ceci:

     from django.db import connection connection._rollback() 

    La discussion plus détaillée de cette question peut être trouvée ici

    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 si vous avez une migration de schemamenus en attente depuis vos models.py. Avec le sud, vous devez mettre à jour le schéma.

     manage.py schemamigration mymodel --auto 

    Vérifie ça

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

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

    Aux parameters de la firebase database.

    J’ai eu cette erreur après avoir restauré une sauvegarde sur une firebase database totalement vide. Il est parti après avoir couru:

     ./manage syncdb 

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

    AVERTISSEMENT: le correctif ci-dessous peut éventuellement entraîner des transactions à l’état ouvert sur la firebase database (au moins avec postgres). Pas sûr à 100% de cela (et comment le réparer), mais je suggère fortement de ne pas faire le patch 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 firebase database, je ne peux effectuer aucune nouvelle action sur la firebase database, même avec une annulation manuelle – j’ai proposé ma propre solution.

    Lorsque je lance le shell Django, je corrige Django pour fermer la connexion à la firebase database dès que des erreurs surviennent. De cette façon, je n’ai jamais à réfléchir à l’annulation des transactions ou à la gestion de 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 

    Si vous rencontrez une telle erreur lors de l’exécution de migrate (South), il se peut que vous ayez beaucoup de changements dans le schéma de firebase database et que vous souhaitiez les gérer tous en même temps. Postgres est un peu méchant à ce sujet. Ce qui fonctionne toujours, c’est de diviser une grande migration en étapes plus petites. Vous utilisez probablement un système de contrôle de version.

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

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

    • Extraire le référentiel vers “n4”, puis synchroniser et migrer.
    • Extraire le référentiel vers “n7”, puis synchroniser et migrer.
    • Checkout repository à “n10”, puis synchroniser et migrer.

    Et tu as fini. 🙂

    Il devrait fonctionner parfaitement.

    Si vous utilisez une version de django antérieure à 1.6, vous devez utiliser l’excellent module xact de Christophe.

    xact est une recette pour gérer les transactions judicieusement dans les applications Django sur PostgreSQL.

    Remarque: à partir de Django 1.6, les fonctionnalités de xact seront fusionnées dans le kernel Django en tant que décorateur atomique. Le code qui utilise xact doit pouvoir être migré en atomique avec juste une recherche et un remplacement. Atomic fonctionne sur des bases de données autres que PostgreSQL, est compatible avec les threads et possède d’autres fonctionnalités intéressantes. changez-le quand vous le pouvez!

    J’ajoute ce qui suit à mon fichier de parameters, car j’aime la fonctionnalité d’autocommit lorsque je joue, mais je ne veux pas l’activer lorsque mon site fonctionne autrement.

    Donc, pour obtenir un autocommit juste en shell, je fais ce petit hack:

     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 n’exécute pas directement manage.py

    J’ai cette erreur dans Django 1.7. Quand je lis dans la documentation

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

    Je me suis un peu méfié. Les erreurs sont survenues lorsque j’ai tenté 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’avais des erreurs d’importation, mais j’ai réussi à le faire fonctionner), même si cela ne semble pas fonctionner pour postgresql, et cela a cassé les migrations au point que n’a pas eu d’événement obtenir un message d’erreur utile, mais plutôt celui du titre des questions.