PERN• 5 MIN READ
Kirito

Kirito

6/10/20265 min read

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 diff to 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.