fix(migrations): rend la migration ingredient_taxonomy_rework safe sur des données existantes
La version générée automatiquement par `prisma migrate diff` castait
directement chaque valeur `category` existante (ancien enum à 18
valeurs) vers le nouvel enum à 7 valeurs — échoue pour toute ligne déjà
seedée, puisqu'aucune ancienne valeur n'existe dans le nouvel enum.
En local ça passait inaperçu (reset complet sur une base vide), mais en
production (données déjà seedées) la migration échoue avec "invalid
input value for enum".
Réécrite pour ajouter les nouvelles colonnes avec une valeur par défaut
sûre (aucun cast des données existantes), puis les substituer aux
anciennes — même logique que les défauts `@default(...)` déjà
documentés dans schema.prisma : seedReferenceData() (relancée à chaque
démarrage du conteneur, voir apps/api/Dockerfile) corrige tout de suite
après la vraie catégorie/sous-catégorie de chaque ligne.
Ajoute aussi un DROP TYPE IF EXISTS défensif : une tentative précédente
de cette migration laisse le type IngredientSubcategory orphelin (son
CREATE TYPE s'exécute hors de la transaction qui échoue plus loin), une
nouvelle tentative sans ce garde-fou échouerait différemment ("type
already exists").
Vérifiée en rejouant l'historique complet des migrations sur une base
de test jetable, avec des lignes portant les anciennes valeurs d'enum
insérées à la main pour reproduire exactement l'échec signalé — la
version corrigée s'applique proprement et préserve les id existants
(donc toute vraie ligne RecipeIngredient qui y référence).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
78e0f89503
commit
d761a3795f
1 changed files with 33 additions and 13 deletions
|
|
@ -1,18 +1,38 @@
|
|||
-- Rewritten after this migration failed on a database that already had
|
||||
-- seeded ingredient rows: the original version (auto-generated by `prisma
|
||||
-- migrate diff`) cast every existing `category` value directly from the
|
||||
-- old 18-value enum to the new 7-value one, which fails for every row
|
||||
-- since none of the old values exist in the new enum. This version instead
|
||||
-- adds the new columns with a safe default (never casting existing data),
|
||||
-- then swaps them in — the same "add with a default, correct for real on
|
||||
-- the next seed run" pattern already used for `IngredientCategory`'s and
|
||||
-- `IngredientSubcategory`'s own `@default(...)` (see their doc comments in
|
||||
-- schema.prisma). `seedReferenceData()` runs right after `migrate deploy`
|
||||
-- on every container start (see apps/api/Dockerfile) and corrects every
|
||||
-- row's real category/subcategory immediately.
|
||||
--
|
||||
-- `DROP TYPE IF EXISTS "IngredientSubcategory"` guards against a previous
|
||||
-- failed attempt at this exact migration: that CREATE TYPE statement runs
|
||||
-- outside the AlterEnum transaction below and so persists even though the
|
||||
-- rest of that failed attempt rolled back — retrying without this guard
|
||||
-- would hit "type already exists".
|
||||
|
||||
-- CreateEnum
|
||||
DROP TYPE IF EXISTS "IngredientSubcategory";
|
||||
CREATE TYPE "IngredientSubcategory" AS ENUM ('LEGUMES', 'FRUITS', 'HERBES_FRAICHES', 'VIANDES', 'VOLAILLES', 'POISSONS', 'CRUSTACES_FRUITS_DE_MER', 'FECULENTS', 'LEGUMINEUSES', 'GRAINES_FRUITS_SECS', 'AUTRES', 'PAINS', 'PATES_A_CUIRE', 'PRODUITS_LAITIERS', 'OEUFS', 'ALTERNATIVES', 'EPICES', 'SAUCES', 'ASSAISONNEMENTS', 'BASES', 'EPAISSISSANTS', 'SUCRES');
|
||||
|
||||
-- AlterEnum
|
||||
BEGIN;
|
||||
-- CreateEnum
|
||||
DROP TYPE IF EXISTS "IngredientCategory_new";
|
||||
CREATE TYPE "IngredientCategory_new" AS ENUM ('PRODUITS_FRAIS', 'BOUCHERIE_POISSONNERIE', 'EPICERIE_SECHE', 'BOULANGERIE', 'CREMERIE_FROMAGE', 'CONDIMENTS_EPICES', 'AIDES_CULINAIRES');
|
||||
ALTER TABLE "ingredients" ALTER COLUMN "category" DROP DEFAULT;
|
||||
ALTER TABLE "ingredients" ALTER COLUMN "category" TYPE "IngredientCategory_new" USING ("category"::text::"IngredientCategory_new");
|
||||
ALTER TYPE "IngredientCategory" RENAME TO "IngredientCategory_old";
|
||||
|
||||
-- AlterTable: add the new columns at their defaults — no cast of existing
|
||||
-- `category` values, so this succeeds regardless of what the table
|
||||
-- currently holds.
|
||||
ALTER TABLE "ingredients" ADD COLUMN "category_new" "IngredientCategory_new" NOT NULL DEFAULT 'EPICERIE_SECHE';
|
||||
ALTER TABLE "ingredients" ADD COLUMN "subcategory" "IngredientSubcategory" NOT NULL DEFAULT 'AUTRES';
|
||||
|
||||
-- Swap the old `category` column (old 18-value enum) out for the new one.
|
||||
ALTER TABLE "ingredients" DROP COLUMN "category";
|
||||
ALTER TABLE "ingredients" RENAME COLUMN "category_new" TO "category";
|
||||
DROP TYPE "IngredientCategory";
|
||||
ALTER TYPE "IngredientCategory_new" RENAME TO "IngredientCategory";
|
||||
DROP TYPE "IngredientCategory_old";
|
||||
ALTER TABLE "ingredients" ALTER COLUMN "category" SET DEFAULT 'EPICERIE_SECHE';
|
||||
COMMIT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ingredients" ADD COLUMN "subcategory" "IngredientSubcategory" NOT NULL DEFAULT 'AUTRES',
|
||||
ALTER COLUMN "category" SET DEFAULT 'EPICERIE_SECHE';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue