Migrating without losing data
db-migrationPROdatabasemigrations
Changes a schema so both the old and new code survive it — and so does a rollback.
Co robi
- Triggers on “add a column”, “rename this field”, “change the type”, “write a migration”.
- Starts from the fact that old and new code overlap in production for minutes, and on a rollback for much longer. Everything else follows.
- Splits a rename into four deploys: add, write to both, backfill, switch reads, drop later. A rename in one step breaks every running instance of the old code at once.
- Puts a drop in a later deploy than the code that stopped using it. Otherwise a rollback leaves code expecting a column that is gone.
- Asks the row count before, not after: a backfill over ten thousand rows is a statement, over ten million it is a batched job, or the lock takes the site down.
- Requires the down migration to be written and read, and if the data cannot come back, to say so in the file itself — so the person at 3am knows before running it.
- Verifies against a copy of production data: an empty database proves only that the syntax parsed.
Do czego się przyda
Migrations do not break on syntax. They break because somebody forgot the five minutes when both versions of the code are live. Duplicates blocking a new unique constraint, nulls in a column about to be required, a lock on a large table — all of it is visible only on real data, and only if the question was asked in advance.
Gdzie go umieścić
- 1Utwórz w projekcie folder .claude/skills/db-migration
- 2Umieść w nim plik SKILL.md z tekstem poniżej
- 3Gotowe. Claude Code sam załaduje skill, gdy zadanie będzie pasować do opisu
Aby skill działał we wszystkich projektach, a nie w jednym, umieść go w ~/.claude/skills zamiast w folderze projektu.
Plik SKILL.md
# Changing a schema while the app is running
The old code and the new code overlap in production for at least a few
minutes, and on a rollback for much longer. Every migration must leave
both able to run.
That single constraint decides almost everything below.
## The safe shapes
**Adding a column:** nullable, or with a default. A `NOT NULL` column
with no default fails the moment old code inserts a row.
**Renaming:** never in one step. Add the new column, write to both,
backfill, switch reads, stop writing the old one, drop it later. Four
deploys, not one. A rename in a single migration breaks every running
instance of the old code at once.
**Changing a type:** the same shape as a rename. Widening (int to
bigint, varchar to text) is usually safe in place; narrowing never is.
**Dropping anything:** in a separate, later deploy from the code thatPlik tego skila należy do kolekcji PRO
Odblokuj dostęp