ewbs / synapse

Synapse : Outil de suivi et de pilotage des projets et actions de simplification administrative en Wallonie et Fédération Wallonie-Bruxelles
GNU General Public License v3.0
0 stars 1 forks source link

Migration : Contraintes de clés étrangères manquantes #40

Open mgrenson opened 7 years ago

mgrenson commented 7 years ago

J'ai identifié que des contraintes semblaient manquer sur les tables demarche_demarchePiece et demarche_demarcheTask : vers démarche vers pièce/tâche

Outre le fait que cela m'a fait perdre plein de temps, il faudrait comprendre quelle en est la raison, car le script de migration en fait bien mention :

mgrenson commented 7 years ago

Raisons

la plupart sont liées au fait que le script utilise la méthode unsigned() avec en enfilade la définition de la clé étrangère. Hors cette méthode ne rend pas l'objet permettant d'enchaîner sur la définition de la clé étrangère (mais aucune erreur n'est cependant rendue, la non application de la contrainte est donc silencieuse, saleté de * de méthode à la c). Il fallait donc appliquer cela en 2 lignes (comme Julian le faisait d'ailleurs, c'est moi qui voulait l'écrire en 1 ligne pour faire genre "je fais moins de lignes"), ou plutôt utiliser la méthode unsignedInteger() qui applique cela d'un coup (ce que j'ai choisi de faire ici).

Il y avait également 3 contraintes manquantes sur un parent_id, et là c'était un simple oubli dans la définition du script.

Clés étrangères manquantes

demarche_demarchePiece

demarche_demarchePiece_revisions

demarche_demarcheTask

demarche_demarcheTask_revisions

demarchesPieces

demarchesTasks

nostra_demarche_nostra_thematiqueabc

nostra_evenement_nostra_thematiqueabc

nostra_public_nostra_thematiqueabc

nostra_publics

nostra_thematiquesabc

nostra_thematiquesadm

mgrenson commented 7 years ago

Il me reste à :

Voilà le script qui sera à exécuter dans tous les environnements lorsque le release 4.3 aura été mis en production (pour les 3 tables avec les parent_id, car le reste pourrait déjà être fait sur la version 4.2) :

DELETE FROM "demarche_demarchePiece" WHERE demarche_id NOT IN (SELECT id FROM demarches); ALTER TABLE "demarche_demarchePiece" ADD CONSTRAINT demarche_demarchepiece_demarche_id_foreign FOREIGN KEY (demarche_id) REFERENCES demarches (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "demarche_demarchePiece" WHERE piece_id NOT IN (SELECT id FROM "demarchesPieces");
ALTER TABLE "demarche_demarchePiece" ADD CONSTRAINT demarche_demarchepiece_piece_id_foreign FOREIGN KEY (piece_id) REFERENCES "demarchesPieces" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "demarche_demarchePiece_revisions" WHERE "demarche_demarchePiece_id" NOT IN (SELECT id FROM "demarche_demarchePiece");
ALTER TABLE "demarche_demarchePiece_revisions" ADD CONSTRAINT demarche_demarchepiece_revisions_demarche_demarchepiece_id_fore FOREIGN KEY ("demarche_demarchePiece_id") REFERENCES "demarche_demarchePiece" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

UPDATE "demarche_demarchePiece_revisions" SET user_id=NULL WHERE user_id NOT IN (SELECT id FROM users);
ALTER TABLE "demarche_demarchePiece_revisions" ADD CONSTRAINT demarche_demarchepiece_revisions_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

DELETE FROM "demarche_demarcheTask" WHERE demarche_id NOT IN (SELECT id FROM demarches);
ALTER TABLE "demarche_demarcheTask" ADD CONSTRAINT demarche_demarchetask_demarche_id_foreign FOREIGN KEY (demarche_id) REFERENCES demarches (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "demarche_demarcheTask" WHERE task_id NOT IN (SELECT id FROM "demarchesTasks");
ALTER TABLE "demarche_demarcheTask" ADD CONSTRAINT demarche_demarchetask_task_id_foreign FOREIGN KEY (task_id) REFERENCES "demarchesTasks" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "demarche_demarcheTask_revisions" WHERE "demarche_demarcheTask_id" NOT IN (SELECT id FROM "demarche_demarcheTask");
ALTER TABLE "demarche_demarcheTask_revisions" ADD CONSTRAINT demarche_demarchetask_revisions_demarche_demarchetask_id_foreig FOREIGN KEY ("demarche_demarcheTask_id") REFERENCES "demarche_demarcheTask" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

UPDATE "demarche_demarcheTask_revisions" SET user_id=NULL WHERE user_id NOT IN (SELECT id FROM users);
ALTER TABLE "demarche_demarcheTask_revisions" ADD CONSTRAINT demarche_demarchetask_revisions_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

UPDATE "demarchesPieces" SET type_id=NULL WHERE type_id NOT IN (SELECT id FROM "demarchesPiecesAndTasksTypes"); ALTER TABLE "demarchesPieces" ADD CONSTRAINT demarchespieces_type_id_foreign FOREIGN KEY (type_id) REFERENCES "demarchesPiecesAndTasksTypes" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

UPDATE "demarchesTasks" SET type_id=NULL WHERE type_id NOT IN (SELECT id FROM "demarchesPiecesAndTasksTypes");
ALTER TABLE "demarchesTasks" ADD CONSTRAINT demarchestasks_type_id_foreign FOREIGN KEY (type_id) REFERENCES "demarchesPiecesAndTasksTypes" (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

DELETE FROM "nostra_demarche_nostra_thematiqueabc" WHERE "nostra_thematiqueabc_id" NOT IN (SELECT id FROM nostra_thematiquesabc);
ALTER TABLE nostra_demarche_nostra_thematiqueabc ADD CONSTRAINT nostra_demarche_nostra_thematiqueabc_nostra_thematiqueabc_id_fo FOREIGN KEY (nostra_thematiqueabc_id) REFERENCES nostra_thematiquesabc (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "nostra_evenement_nostra_thematiqueabc" WHERE "nostra_thematiqueabc_id" NOT IN (SELECT id FROM nostra_thematiquesabc);
ALTER TABLE nostra_evenement_nostra_thematiqueabc ADD CONSTRAINT nostra_evenement_nostra_thematiqueabc_nostra_thematiqueabc_id_f FOREIGN KEY (nostra_thematiqueabc_id) REFERENCES nostra_thematiquesabc (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

DELETE FROM "nostra_public_nostra_thematiqueabc" WHERE "nostra_thematiqueabc_id" NOT IN (SELECT id FROM nostra_thematiquesabc);
ALTER TABLE nostra_public_nostra_thematiqueabc ADD CONSTRAINT nostra_public_nostra_thematiqueabc_nostra_thematiqueabc_id_fore FOREIGN KEY (nostra_thematiqueabc_id) REFERENCES nostra_thematiquesabc (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE;

ALTER TABLE "nostra_publics" ALTER COLUMN "parent_id" DROP NOT NULL; UPDATE "nostra_publics" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_publics");
ALTER TABLE nostra_publics ADD CONSTRAINT nostra_publics_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_publics (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

ALTER TABLE "nostra_thematiquesabc" ALTER COLUMN "parent_id" DROP NOT NULL; UPDATE "nostra_thematiquesabc" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_thematiquesabc");
ALTER TABLE nostra_thematiquesabc ADD CONSTRAINT nostra_thematiquesabc_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_thematiquesabc (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

ALTER TABLE "nostra_thematiquesadm" ALTER COLUMN "parent_id" DROP NOT NULL; UPDATE "nostra_thematiquesadm" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_thematiquesadm");
ALTER TABLE nostra_thematiquesadm ADD CONSTRAINT nostra_thematiquesadm_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_thematiquesadm (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

mgrenson commented 7 years ago

J'ai appliqué les contraintes de clé étrangères dans tous les environnements (dév, test, valid, prod). Nickel, et aucune ligne incohérente n'avait été détectée (donc aucune requête de delete n'a été appliquée) (sauf en local, où j'avais volontairement foutu le bordel)


J'ai également modifié le code de synapse là où on faisait référence à parent_id = 0 : je me suis arrangé pour que cela fonctionne dans les cas où parent_id vaut 0 ou null, de manière transitoire (à nettoyer dans le release 4.4).


J'ai également droppé les not null sur les parent_id : ALTER TABLE "nostra_publics" ALTER COLUMN "parent_id" DROP NOT NULL; ALTER TABLE "nostra_thematiquesabc" ALTER COLUMN "parent_id" DROP NOT NULL; ALTER TABLE "nostra_thematiquesadm" ALTER COLUMN "parent_id" DROP NOT NULL; (car après application du release 4.3 la synchro va vouloir mettre null dans les parent_id qui valaient 0 si elle passe avant que je n'ai eu le temps d'effectuer les requêtes restantes)


Et reste alors celles-là à appliquer, après le déploiement du release 4.3 :

UPDATE "nostra_publics" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_publics"); ALTER TABLE nostra_publics ADD CONSTRAINT nostra_publics_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_publics (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

UPDATE "nostra_thematiquesabc" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_thematiquesabc"); ALTER TABLE nostra_thematiquesabc ADD CONSTRAINT nostra_thematiquesabc_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_thematiquesabc (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;

UPDATE "nostra_thematiquesadm" SET parent_id=NULL WHERE parent_id NOT IN (SELECT id FROM "nostra_thematiquesadm"); ALTER TABLE nostra_thematiquesadm ADD CONSTRAINT nostra_thematiquesadm_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES nostra_thematiquesadm (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE SET NULL;