NotVibesCoded logo

AI wrote your migration: trusting database changes you didn't write

Agents write migrations fast, and database mistakes are the ones you can't roll back from coffee. What to verify before an AI-generated migration touches production data.

Published 2 min read

Of everything you can let an agent generate, database migrations deserve the most suspicion. Application code can be redeployed; bad data is forever. And agents write migrations with the same confidence they write CSS.

Why migrations are the danger zone

  • Irreversible by default. Most migration frameworks make down migrations optional. Agents skip them.
  • Lock behavior is invisible. ALTER TABLE on a million-row table locks writes. The agent doesn't know your table has a million rows.
  • Data migrations hide in schema migrations. Backfilling a new column in the same transaction as adding it is how you learn about lock timeouts at 2 AM.
  • No staging parity. The migration ran fine on the agent's empty local database. Production has data, and data has opinions.

The pre-merge checklist

1. Is it reversible?

Every migration needs a down path that's actually been thought through, not an auto-generated stub. Ask the agent explicitly: "write the rollback first." If the rollback is "restore from backup," that's an answer, but it should be a conscious one.

2. What's the lock impact?

For Postgres (and most databases), know these before approving:

  • Adding a column with a default → rewrites the table on older versions; use the multi-step pattern (add nullable → backfill → set default → set not null)
  • Creating an index → CONCURRENTLY, or it locks writes
  • Changing a column type → full rewrite; needs the expand/contract pattern

If the agent's migration does any of these in one step on a large table, send it back.

3. Data migrations are separate

Schema change and data backfill in one migration is the classic footgun. The rule: schema migrations change structure; data migrations change rows; never both in one deploy. Agents love combining them because it's "efficient." It's efficient the way skipping the pre-flight check is efficient.

4. Run it against realistic data

The agent tested on an empty database. You need:

  • A staging database with production-like volume (anonymized dump, or generated fixtures at scale)
  • EXPLAIN on any migration-time queries
  • Timing: if it takes 10 seconds on 10k rows, do the math for 10M

5. Check the framework's footguns

Every migration tool has them. For the common ones:

  • Django: RunPython without atomic = False on large tables; missing elidable operations
  • Prisma: a single prisma migrate deploy doing more than you reviewed: always prisma migrate diff first
  • Raw SQL: no transaction wrapping, no statement timeout

The workflow that works

  1. Agent drafts the migration from your description
  2. You review against this checklist (5 minutes)
  3. CI runs it against a seeded staging-scale database
  4. Deploy schema and data changes separately
  5. Verify rollback on staging before production

Agents are genuinely good at the tedious parts of migrations, the boilerplate, the syntax, the framework idioms. Let them do that. Keep the judgment, reversibility, locks, data volume, for yourself. That's the part that protects the data.

Related articles