Si vous ajoutez un champ non nul, vous devez le faire en deux migrations :
AddField
et RunPython
pour le peupler
AlterField
pour changer le champ en non nul
Explication
Sur PostgreSQL et SQLite, ce problème peut survenir si vous avez une commande RunPython
suffisamment complexe combinée avec des modifications de schéma dans la même migration. Par exemple, si vous ajoutez un champ non nul, les étapes de migration typiques sont les suivantes :
AddField
pour ajouter le champ comme nullable
RunPython
pour le peupler
AlterField
pour changer le champ en non nul
Sur SQLite et Postgres, cela peut causer des problèmes car tout est fait dans une seule transaction.
Les documents Django contiennent un avertissement spécifique à ce sujet :
Sur les bases de données prenant en charge les transactions DDL (SQLite et PostgreSQL), les opérations RunPython n'ont pas de transactions automatiquement ajoutées, en dehors des transactions créées pour chaque migration. Ainsi, sur PostgreSQL par exemple, vous devriez éviter de combiner des modifications de schéma et des opérations RunPython dans la même migration, sinon vous pourriez rencontrer des erreurs comme OperationalError: cannot ALTER TABLE "mytable" because it has pending trigger events.
Si tel est le cas, la solution est de séparer votre migration en plusieurs migrations. En général, la manière de diviser consiste à avoir une première migration contenant les étapes jusqu'à la commande run_python et une seconde migration contenant toutes celles après. Ainsi, dans le cas décrit ci-dessus, le modèle serait le AddField
et RunPython
dans une migration, et le AlterField
dans une seconde.
2 votes
Cette question est similaire : stackoverflow.com/questions/28429933/… et les réponses étaient plus utiles pour moi.
1 votes
J'ai rencontré le même problème avec Postgres v10 (mais pas avec Postgres v.12). Problème résolu, en ajoutant un fichier de migration séparé.