Kirito
The Prisma Migration That Dropped a Production Column (No Way to Recover)
A Prisma migration that looked safe – renaming a column – turned into a silent data loss because we forgot to add a @map attribute. 50,000 rows lost their values.
The Prisma Migration That Dropped a Production Column (No Way to Recover)
"Where did the user's phone number go?"
We had a simple schema change: rename phone to phone_number.
I changed the Prisma schema, ran prisma migrate dev, and pushed to production.
But the column wasn't renamed – it was dropped. And all 50,000 phone numbers were gone.
The Setup
Original schema:
model User { id Int @id @default(autoincrement()) email String @unique phone String // ← this column }
I changed it to:
model User { id Int @id @default(autoincrement()) email String @unique phone_number String // ← renamed }
The Migration
npx prisma migrate dev --name rename_phone_column
Prisma generated this SQL:
-- Prisma generated (WRONG!) ALTER TABLE "User" DROP COLUMN "phone"; ALTER TABLE "User" ADD COLUMN "phone_number" TEXT;
Instead of RENAME COLUMN, Prisma dropped and recreated the column. All data in phone was lost.
Why? Because Prisma doesn't know you want to rename. It sees a removed field and a new field – and assumes you want to drop+add.
The Fix (Prevention)
You must use @map to tell Prisma the underlying database column name:
model User { id Int @id @default(autoincrement()) email String @unique phone_number String @map("phone") // ← maps to existing column name }
Then the migration becomes a no‑op (column already exists).
After deploying, you can later remove the @map in a second migration.
The Recovery
We had to restore from a backup taken 6 hours before.
# Restore from AWS RDS snapshot aws rds restore-db-instance-from-db-snapshot --db-instance-identifier mydb-restored --db-snapshot-identifier mydb-snapshot
Then manually export the phone column and join back. Lost 4 hours of new orders.
What I Learned
- Prisma doesn't auto‑detect renames – you must use
@map. - Always check the generated SQL before applying to production.
- Use
prisma migrate diffto see what will happen. - Never trust a migration without a backup.
Now our CI runs prisma migrate diff and fails if it sees DROP COLUMN on non‑nullable fields.