Désactiver les vérifications de clé étrangère PostgreSQL pour les migrations

je crée beaucoup de migrations qui ont des clés étrangères dans PostgreSQL 9.4.

cela crée un mal de tête parce que les tables doivent toutes ÊTRE dans l'ordre exact attendu par les clés étrangères quand elles sont migrées. Cela devient encore plus délicat si je dois exécuter des migrations à partir d'autres paquets dont mes nouvelles migrations dépendent pour une clé étrangère.

dans MySQL, je peux simplifier cela en ajoutant simplement SET FOREIGN_KEY_CHECKS = 0; en haut de mon fichier de migration. Comment puis-je faire cela temporairement dans PostgresSQL uniquement pour la longueur du code de migration?

BTW, en utilisant le constructeur de schéma Laravel pour cela.

17
demandé sur eComEvo 2016-06-30 04:03:56

2 réponses

PostgreSQL ne supporte aucune option de configuration, mais il y a une autre possibilité.

postgres=# \d b
        Table "public.b"
┌────────┬─────────┬───────────┐
│ Column │  Type   │ Modifiers │
╞════════╪═════════╪═══════════╡
│ id     │ integer │           │
└────────┴─────────┴───────────┘
Foreign-key constraints:
    "b_id_fkey" FOREIGN KEY (id) REFERENCES a(id) DEFERRABLE

l'intégrité référentielle dans Postgres est implémentée par des triggers, et vous pouvez désactiver les triggers sur table. Avec cette méthode, vous pouvez télécharger toutes les données (risque), mais il est beaucoup plus rapide - parce que le contrôle sur les grandes données est coûteux. Et si votre téléchargement est sûr, alors vous pouvez le faire.

BEGIN;
ALTER TABLE b DISABLE TRIGGER ALL;
-- now the RI over table b is disabled
ALTER TABLE b ENABLE TRIGGER ALL;
COMMIT;

la prochaine possibilité est d'utiliser des contraintes différées. Ce mouvement contrainte de vérifier au moment de la validation. Vous ne devez donc pas respecter l'ordre avec INSERT commandes:

ALTER TABLE b ALTER CONSTRAINT b_id_fkey DEFERRABLE;

BEGIN
postgres=# SET CONSTRAINTS b_id_fkey DEFERRED;
SET CONSTRAINTS
postgres=# INSERT INTO b VALUES(100); -- this is not in a table
INSERT 0 1
postgres=# INSERT INTO b VALUES(10);
INSERT 0 1 
postgres=# COMMIT;
ERROR:  insert or update on table "b" violates foreign key constraint "b_id_fkey"
DETAIL:  Key (id)=(100) is not present in table "a".

Cette méthode doit être préféré pour vous, parce que les données insérées seront vérifiées.

27
répondu Pavel Stehule 2016-06-30 04:08:40

Pour la migration, il est plus facile de désactiver tous les déclencheurs avec:

SET session_replication_role = replica;

Et après la migration réactiver tous les

SET session_replication_role = DEFAULT;
20
répondu andro83 2018-03-31 05:44:37