Accueil / Articles / Établir une ligne de référence pour une base de données existante dans Prisma sans exécuter migrate reset

Établir une ligne de référence pour une base de données existante dans Prisma sans exécuter migrate reset

Découvrez pourquoi Prisma signale des écarts dans une base de données existante, pourquoi la réinitialisation lors de la migration n’est pas la solution adéquate, et comment établir une référence de base avec db pull, migrate diff et migrate resolve.

1029 mots

Point Prisma Migrate fonctionne sur une base de données qui contient déjà des tables et des données, et il est très probable que la première exécution de npx prisma migrate dev s’arrête avec un avertissement de dérive et propose de tout réinitialiser. Cet avis indique que la base de données contient une structure dont l’historique des migrations n’a aucune connaissance. L’accepter supprimera vos données. Ce guide explique pourquoi ce conflit se produit, pourquoi la réinitialisation n’est presque jamais la bonne solution pour une base de données importante, et comment établir un état de référence du schéma existant afin que Prisma le considère comme point de départ et n’applique des modifications qu’à partir de là.

Pourquoi Prisma détecte un conflit

Prisma Migrate conserve deux traces de l’évolution de votre schéma : les fichiers de migration situés dans prisma/migrations et une table nommée _prisma_migrations au sein de la base de données, qui indique quels fichiers ont été appliqués. Lorsque vous exécutez migrate dev, Prisma reconstitue l’historique des migrations sur une base de données temporaire et compare le résultat avec celui de la base réelle.

Si la base de données réelle contient déjà des tables que aucune migration n’a créées, par exemple parce qu’elle a été construite manuellement, avec un autre outil ou à l’aide d’une version antérieure de l’application, les deux ne correspondent pas. Prisma qualifie cela de dérive. Comme migrate dev est une commande de développement, sa solution par défaut consiste à effacer la base de données et à la reconstruire à partir de l’historique des migrations, ce qui entraîne une proposition de réinitialisation. Cela est acceptable pour une base locale temporaire, mais destructeur pour tout autre usage.

Si vous souhaitez en savoir plus sur le rôle de la base de données shadow dans cette comparaison, consultez Prisma’s shadow database and naming mismatches.

Pourquoi migrate reset n’est pas la bonne solution

npx prisma migrate reset supprime la base de données, ou chaque table de son schéma, la recrée à partir de vos migrations et exécute des scripts de génération de données. Toutes les lignes existantes sont perdues. Dans le cas d’une base de données contenant des utilisateurs réels, des commandes ou du contenu, il ne s’agit pas de résolution de conflits mais bien de perte de données.

L’approche plus appropriée consiste à laisser la base de données tranquille et à mettre plutôt à jour la vision que Prisma a du système en fonction d’elle. Pour ce faire, vous enregistrez la structure actuelle comme première migration et indiquez à Prisma que cette migration est déjà en place.

Étape par étape pour établir une base de référence

Étape 1 : Analyser la base de données existante

Exécutez npx prisma db pull. Prisma se connecte à la base de données, lit ses tables, colonnes, index et relations, puis écrit les modèles correspondants dans schema.prisma. Après cette étape, le fichier de schéma décrit la base de données telle qu’elle est réellement.

Étape 2 : Générer une migration de référence sans l’appliquer

Créez un dossier pour la ligne de référence, par exemple prisma/migrations/0_init. Le préfixe 0_ permet à ce dossier d’être trié avant toutes les migrations ultérieures datées. Ensuite, génèrez le SQL nécessaire pour créer le schéma actuel à partir de rien et enregistrez-le dans ce dossier, en utilisant npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql. Dans les versions récentes de Prisma, l’option cible peut être nommée --to-schema à la place, il convient donc de vérifier npx prisma migrate diff --help selon votre version.

Cette étape est importante car elle génère le fichier de migration sans toucher à la base de données. Une erreur fréquente consiste à exécuter npx prisma migrate dev --name baseline à ce stade. Sur une base de données qui possède déjà des tables et aucun historique de migration, cette commande détecte la même déviation qu’auparavant et demande de réinitialiser à nouveau, ce qui est précisément ce que l’on cherche à éviter. Le SQL de référence ne doit jamais être exécuté sur la base de données existante, car ses tables y sont déjà présentes.

Étape 3 : Marquer la référence comme appliquée

Exécutez npx prisma migrate resolve --applied 0_init. L’argument correspond au nom du dossier de migration. Si un dossier a été créé avec une date et heure, comme 20250101120000_baseline, vous devez indiquer ce nom complet, et non simplement baseline.

Cette commande ne met pas en œuvre de requête SQL sur vos tables. Elle insère une ligne dans _prisma_migrations indiquant que la base de référence a été appliquée. En réalité, vous modifiez les registres de Prisma afin qu’il considère la structure actuelle comme intentionnelle et valide.

Comment cela résout le conflit

Cela ressemble à un conflit de fusion Git : lorsque votre branche ne contient pas les modifications déjà présentes sur main, vous mettez à jour la branche plutôt que de supprimer main. Ici, la base de données est à jour, et vous mettez l’historique de Prisma en conformité avec elle.

Lorsque la base de référence est enregistrée, la prochaine exécution de npx prisma migrate dev réexécute 0_init dans la base de données fantôme, obtient la même structure que la base réelle et ne détecte aucune différence. Dès lors, lorsque vous modifiez schema.prisma, Prisma génère une nouvelle migration contenant uniquement les différences et n’applique que celles-ci.

Pourquoi c’est important pour les grandes bases de données

La création d’une ligne de référence est particulièrement utile lorsque la base de données contient une grande quantité de données. Avec la ligne de référence enregistrée dans _prisma_migrations et le schéma correspondant à la base de données en ligne, Prisma laisse intactes les tables et les lignes existantes et n’applique que les modifications nouvelles, de sorte que votre table users reste inchangée.

Tenez compte de quelques points pratiques :

  • Exécutez migrate resolve --applied une fois pour chaque environnement existant, comme le staging et la production, car chaque base de données possède sa propre table _prisma_migrations.
  • Dans la production, appliquez les migrations ultérieures avec npx prisma migrate deploy, et non avec migrate dev, qui n’est destiné qu’au développement.
  • Communiquez le dossier de la ligne de référence au système de contrôle de version afin que tous les développeurs et les tâches CI partagent le même point de départ.

Points clés

  • Un avertissement de dérive dans une base de données existante signifie que l’historique des migrations de Prisma est manquant, et non que la base de données est incorrecte.
  • Le réinitialisation supprime les données ; considérez-la uniquement comme un outil pour des bases de données locales temporaires.
  • Déterminez la ligne de base en analysant avec db pull, en générant du SQL avec migrate diff --from-empty, et en l’enregistrant avec migrate resolve --applied.
  • N’utilisez pas migrate dev pour créer la ligne de base à partir d’une base de données déjà remplie, car cela déclenche la même demande de réinitialisation.
  • Une fois la ligne de base définie, Prisma gère uniquement les modifications incrémentielles, et les données existantes restent inchangées.