Le problème
Tu veux renommer user.email_addr en user.email. Prisma génère une migration ALTER TABLE ... RENAME COLUMN. Sur une grosse table, ça lock pendant la migration — l'API tombe.
La recette "expand & contract"
Étape 1 — Expand (ajouter)
Ajoute la nouvelle colonne nullable, en parallèle de l'ancienne :
model User {
email_addr String // ancien
email String? // nouveau, nullable
}
Migration rapide (juste un ADD COLUMN non-bloquant).
Étape 2 — Backfill (copier)
Un script qui copie en chunks :
let cursor = 0;
while (true) {
const batch = await prisma.user.findMany({
where: { email: null, id: { gt: cursor } },
take: 1000,
orderBy: { id: "asc" },
});
if (batch.length === 0) break;
await prisma.$transaction(
batch.map((u) =>
prisma.user.update({
where: { id: u.id },
data: { email: u.email_addr },
})
)
);
cursor = batch[batch.length - 1].id;
}
Étape 3 — Switch (déployer le code qui lit/écrit email)
Le code lit email mais continue à écrire les deux.
Étape 4 — Contract (supprimer)
Une fois 100 % des requêtes basculées, drop email_addr.
Bilan
4 déploiements au lieu d'un, mais 0 downtime. Sur une vraie prod, ça ne se négocie pas.