Of everything Claude Code can do to your app, changing the database is the one that can't be undone with just a click. Code you can roll back. A dropped column with a year of customer data in it is gone unless you have proper backups.
Most apps built with Claude Code use a tool like Prisma or Drizzle that manages the database structure through migrations, which are small files describing each change, run in order. The tools make this easy, and the most common way it goes wrong is running the development command against the real database.
Development commands and production commands
Prisma is a good example because the line is drawn clearly in its CLI reference. prisma migrate dev is labeled "For use in development environments only, requires shadow database." prisma migrate reset is also development-only, and its first step "Drops the database/schema if possible." The command meant for real servers is prisma migrate deploy, which "applies all pending migrations" and is "primarily used in non-development environments."
The danger is that Claude, trying to get past an error, reaches for whichever command made the error go away on your laptop. If your production database connection is the one in your environment at that moment, a reset there is a disaster.
The protection is boring and effective. Keep production credentials out of your local environment file entirely, so the only database Claude can reach from your laptop is a local one. Tell it in your CLAUDE.md that migrate reset and migrate dev never run against production. And use Claude Code's permission rules to make Claude ask before any command that starts with prisma migrate reset.
This site goes further. The migration SQL for production changes is written by hand to match the schema, reviewed, and applied with migrate deploy. Here's a real one, from the change that added the key-points box to blog posts:
ALTER TABLE "BlogPost" ADD COLUMN "keyPoints" TEXT;One line, nothing removed, and the comment above it in the file calls it "Additive, nullable." Most migrations should look like that.
Four habits keep data safe from there.
Read the SQL before it runs. Migration tools generate SQL files. Open them. Look for DROP, DELETE, TRUNCATE, or ALTER COLUMN that changes a type. Ask Claude to explain each line in plain English if you can't read SQL yourself.
Add, then remove later. Want to rename a column? Don't, at least not in one step. Add the new column, copy the data across, switch the code to use it, and remove the old column in a later release once nothing reads it. A rename done in one go is a drop and an add, and some tools will happily lose the data in between.
Back up right before. A nightly backup from yesterday still loses today. Take a fresh dump immediately before any migration that changes or removes something, and make sure you know how to restore it. We've covered why backups matter with an AI agent deleting a live database.
Try it on a copy first. Restore last night's backup into a scratch database and run the migration there. If it works on a real copy of your data, it'll almost certainly work in production.
A prompt that bakes most of this in: "Add a nullable column for X. Create the migration, show me the SQL, and don't apply it to any database. Explain anything in the SQL that removes or changes existing data." Then you apply it, after reading it, with the production command. That one review step is cheap, and it's where data loss gets caught.
Sources
Prisma: CLI reference (Prisma ORM v7) - migrate dev being for development environments only, migrate reset being development-only and dropping the database or schema as its first step, and migrate deploy applying pending migrations in non-development environments.
ClaudeFolio migration history - The additive, nullable migration adding the keyPoints column to blog posts.






