Développement #47916
Incohérences lors de la duplication d'un guichet avec des sources d'exceptions
0%
Description
Sens, chaque exception est en double et la source est en double : https://agendas.demarches.ville-sens.fr/manage/agendas/56/settings
Essonne, chaque exception est en double, une seule source, le doublon a perdu son attribut « source » et son flag « external » : https://agendas.demarches.essonne.fr/manage/agendas/1/settings
Je regarde...
Files
Associated revisions
agendas: do not import exception from settings when duplicating (#47916)
agendas: add unicity constraint on exception source slug (#47916)
History
Updated by Valentin Deniaud about 4 years ago
Et donc le coupable, « Copier le paramétrage du guichet »...
En plus du patch pour éviter cette duplication, il va falloir une migration qui ajoute une contrainte d'unicité sur le slug de la source d'exception, et vire les doublons au préalable.
Updated by Valentin Deniaud about 4 years ago
Side effect, ça fait des exceptions qu'on ne peut plus désactiver, #47915.
Updated by Valentin Deniaud about 4 years ago
- File 0001-agendas-fix-duplication-of-desk-with-external-except.patch 0001-agendas-fix-duplication-of-desk-with-external-except.patch added
- File 0002-agendas-add-unicity-constraint-on-exception-source-s.patch 0002-agendas-add-unicity-constraint-on-exception-source-s.patch added
- Tracker changed from Bug to Développement
- Status changed from Nouveau to Solution proposée
- Patch proposed changed from No to Yes
0001 pour fixer le bug, 0002 pour réparer les db et rajouter une contrainte pour être sûr que ça n'arrive plus...
La migration de 0002 doit se faire en deux fois, parce que une migration = un bloc atomic, et que django ne peut pas bouger les données et ajouter des contraintes au champs en même temps (erreur « pending trigger events »). En vrai c'est pas fou, on aimerait bien de l'atomicité, je m'y repenche demain.
Updated by Valentin Deniaud about 4 years ago
Valentin Deniaud a écrit :
je m'y repenche demain.
C'est un comportement documenté et je n'ai pas l'impression qu'il y ait de contournement, https://docs.djangoproject.com/en/1.11/ref/migration-operations/#django.db.migrations.operations.RunPython :
you should avoid combining schema changes and RunPython operations in the same migration or you may hit errors like OperationalError: cannot ALTER TABLE "mytable" because it has pending trigger events
Mais en fait c'est un faux problème que je me posais : comme la première migration assure l'unicité, et que la deuxième ajoute la contrainte, je me disais qu'un doublon pouvait très hypothétiquement être créé dans l'intervalle et faire échouer le truc. Mais un doublon ne peut plus être créé, c'est assuré par le premier patch. Donc tout va bien.
Updated by Valentin Deniaud about 4 years ago
- Status changed from Solution proposée to En cours
Il y a deux trucs à corriger
- ne pas importer les exceptions si on est dans un cas de duplication (et laisser ensuite la duplication de source se faire, on pourrait faire le choix inverse mais ça serait moins clair)
- ne pas dupliquer les exceptions externes, parce qu'elles sont liées à la source du guichet initial et on veut pas ça
Et en tapant ça je m'aperçois que le deuxième point n'est pas spécifique aux exceptions jours fériés, c'est valable avec toutes les sources (import d'un ICS -> duplication -> suppression de l'ICS dans le guichet dupliqué (rien ne se passe) -> suppression de l'ICS dans le fichier initial (exception supprimées dans les deux guichets).
Updated by Valentin Deniaud about 4 years ago
- File 0002-agendas-do-not-import-exception-from-settings-when-d.patch 0002-agendas-do-not-import-exception-from-settings-when-d.patch added
- File 0003-agendas-add-unicity-constraint-on-exception-source-s.patch 0003-agendas-add-unicity-constraint-on-exception-source-s.patch added
- File 0001-agendas-set-proper-exception-source-when-duplicating.patch 0001-agendas-set-proper-exception-source-when-duplicating.patch added
- Status changed from En cours to Solution proposée
Voilà, en différenciant les deux points du dessus dans les deux premiers patches.
Updated by Valentin Deniaud about 4 years ago
Valentin Deniaud a écrit :
Et en tapant ça je m'aperçois que le deuxième point n'est pas spécifique aux exceptions jours fériés, c'est valable avec toutes les sources (import d'un ICS -> duplication -> suppression de l'ICS dans le guichet dupliqué (rien ne se passe) -> suppression de l'ICS dans le fichier initial (exception supprimées dans les deux guichets).
Mais ça s'autocorrige tout seul au bout d'une heure avec la commande qui synchronise les ICS (cycle qui supprime/remet les exceptions), c'est pour ça que c'est passé sous les radars. Pas besoin de migration qui rattrape, donc.
Updated by Valentin Deniaud about 4 years ago
- Subject changed from Source d'exception jours fériés, n'importe quoi sur la prod to Incohérences lors de la duplication d'un guichet avec des sources d'exceptions
Updated by Benjamin Dauvergne about 4 years ago
0001 : ok
0002 : ok
0003 : ok, juste je me demande si prendre le premier des doublons d'une source ayant des exceptions est suffisant, par rapport à leur état (source.enabled)
Note pour moi : pour le 0003 il faut juste se mettre dans l'idée quand on lit qu'en fait les sources passent leur temps à effacer toutes les exceptions qui leur sont liées à chaque fois qu'elles se mettent à jour, donc en fait on a très peu de chance de trouver des exceptions incohérentes (lièe au mauvais bureau, j'ai eu un peu du mal à comprendre pourquoi on pouvait en faire aussi peu) et supprimer les sources en trop suffit (aucune source ne manque et il n'y a pas de doublon de source pour le type de source "ics")
On peut peut-être remplacé ça par un update_or_create() maintenant qu'on a un index d'unicité :
try: source = TimePeriodExceptionSource.objects.get(desk=self, settings_slug=slug) except TimePeriodExceptionSource.DoesNotExist: source = TimePeriodExceptionSource.objects.create( desk=self, settings_slug=slug, enabled=False )
Updated by Benjamin Dauvergne about 4 years ago
- Status changed from Solution proposée to Solution validée
Updated by Valentin Deniaud about 4 years ago
Thx pour la relecture.
Benjamin Dauvergne a écrit :
0003 : ok, juste je me demande si prendre le premier des doublons d'une source ayant des exceptions est suffisant, par rapport à leur état (source.enabled)
Quand tu dupliques une première fois, tu te retrouves avec deux sources enabled, l'une créée par l'import lors du save(), l'autre par la duplication. On veut garder la première, qui a correctement créé ses exceptions, et pas la seconde. Donc on voit qu'on ne peut pas se fier à enabled pour prendre des décisions ici.
Lors des duplications suivantes, on peut se retrouver avec plusieurs sources enabled qui ont des exceptions, il suffit d'en choisir une au pif.
On peut peut-être remplacé ça par un update_or_create() maintenant qu'on a un index d'unicité :
En vrai je relis cette ligne et je ne comprends pas pourquoi il n'y a pas un get_or_create (certes il n'y a pas d'index d'unicité mais je ne pense pas que ce soit la raison vu que le même pb se pose avec get tout court). Par contre update_or_create je pense pas, on ne veut pas mettre à jour la valeur de enabled. Trop frileux pour y toucher ici en tout cas.
Updated by Valentin Deniaud about 4 years ago
Valentin Deniaud a écrit :
Bon aller à la rigueur il y a un cas où on peut se permettre d'être plus intelligent :Benjamin Dauvergne a écrit :
0003 : ok, juste je me demande si prendre le premier des doublons d'une source ayant des exceptions est suffisant, par rapport à leur état (source.enabled)
Quand tu dupliques une première fois, tu te retrouves avec deux sources enabled, l'une créée par l'import lors du save(), l'autre par la duplication. On veut garder la première, qui a correctement créé ses exceptions, et pas la seconde. Donc on voit qu'on ne peut pas se fier à enabled pour prendre des décisions ici.
Lors des duplications suivantes, on peut se retrouver avec plusieurs sources enabled qui ont des exceptions, il suffit d'en choisir une au pif.
- duplication comme je décris, le guichet dupliqué a une source enabled avec des exceptions, l'autre enabled sans
- quelqu'un vient désactiver la source avec des exceptions
- la migration risque de garder la source enabled qui n'a pas d'exceptions, alors qu'on aurait voulu celle dans un état cohérent.
J'ajoute un petit if qui gère ça et je pousse.
Updated by Valentin Deniaud about 4 years ago
- Status changed from Solution validée to Résolu (à déployer)
commit c1d5eb32ee80623810c8a016d33e612bec0b1ffb Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Wed Oct 21 17:47:38 2020 +0200 agendas: add unicity constraint on exception source slug (#47916) commit bb3e011beaec6dddedc0a30698e03e74f8f95bb3 Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Thu Oct 22 11:59:31 2020 +0200 agendas: do not import exception from settings when duplicating (#47916) commit f880490e00e82986733cbcf2369d6c5f7e80213f Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Thu Oct 22 11:58:55 2020 +0200 agendas: set proper exception source when duplicating (#47916)
Updated by Frédéric Péters about 4 years ago
- Status changed from Résolu (à déployer) to Solution déployée
agendas: set proper exception source when duplicating (#47916)