web-dev-qa-db-fra.com

Django-DB-Migrations: ne peut pas ALTER TABLE car il a des événements de déclenchement en attente

Je veux supprimer null = True d'un TextField:

-    footer=models.TextField(null=True, blank=True)
+    footer=models.TextField(blank=True, default='')

J'ai créé une migration de schéma:

manage.py schemamigration fooapp --auto

Étant donné que certaines colonnes de pied de page contiennent NULL j'obtiens ce error si j'exécute la migration:

Django.db.utils.IntegrityError: la colonne "footer" contient des valeurs nulles

J'ai ajouté ceci à la migration du schéma:

    for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
        sender.footer=''
        sender.save()

Maintenant je reçois:

Django.db.utils.DatabaseError: cannot ALTER TABLE "fooapp_emailsender" because it has pending trigger events

Qu'est-ce qui ne va pas?

96
guettli

Chaque migration se fait à l'intérieur d'une transaction. Dans PostgreSQL, vous ne devez pas mettre à jour la table, puis modifier le schéma de la table en une seule transaction.

Vous devez diviser la migration des données et la migration du schéma. Créez d'abord la migration des données avec ce code:

 for sender in orm['fooapp.EmailSender'].objects.filter(footer=None):
    sender.footer=''
    sender.save()

Créez ensuite la migration du schéma:

manage.py schemamigration fooapp --auto

Vous avez maintenant deux transactions et la migration en deux étapes devrait fonctionner.

110
guettli

Une autre raison à cela peut-être parce que vous essayez de définir une colonne sur NOT NULL quand il a déjà des valeurs NULL.

111
maazza

Je viens de toucher ce problème. Vous pouvez également utiliser db.start_transaction () et db.commit_transaction () dans la migration de schéma pour séparer les modifications de données des modifications de schéma. Probablement pas assez propre pour avoir une migration de données distincte, mais dans mon cas, j'aurais besoin d'un schéma, de données, puis d'une autre migration de schéma, j'ai donc décidé de tout faire en même temps.

9
clime