Database Migration Guardrails
Guide for Database Migration Guardrails
๐ก๏ธ Database Migration Guardrails
CRITICAL: Following these rules prevents database corruption, data loss, and "checksum mismatch" errors that force wipes.
๐ซ Rule 1: The Principle of immutability
NEVER modify a migration file (
.sql) after it has been committed or run.- Why?
sqlxstores a checksum of every applied migration in the_sqlx_migrationstable. If you edit a file on disk (e.g., to fix a typo), the checksum changes. The next time anyone tries to run migrations,sqlxwill panic, detecting corruption. - The Consequence: Often the only easy fix for a checksum mismatch is
sqlx database reset, which WIPES ALL DATA. - The Correct Way: If you make a mistake in
001_initial.sql, create002_fix_typo.sqlto correct it.
โฐ Rule 2: Timestamp Versioning
ALWAYS use timestamp-based versioning. Do not use plain integers.
- Bad:
045_add_tables.sql,046_update.sql - Good:
20260124120000_add_tables.sql - Why? Integer collisions are guaranteed on a team. Timestamps allow multiple developers to create migrations concurrently without conflict (they just run in chronological order).
- How:
# Inside /rust-engine sqlx migrate add description_of_change # Creates: 20260124123456_description_of_change.up.sql
๐งช Rule 3: The "Fresh Start" Test
Migrations must run successfully on an empty database.
- The Problem: A migration
003.sqlmight try to insert data into a table created in001.sql. If you accidentally deleted that table in002.sqlor messed up dependencies, your entire chain is broken. - The Test: Before merging any PR with DB changes, verify the chain:
# Local Verification sqlx database drop -y sqlx database create sqlx migrate run - If this fails: You have a broken migration dependency. Fix it immediately before committing.
๐ ๏ธ Recovery Procedures
Scenario: Checksum Mismatch (Local Dev)
If you edited a file locally and haven't pushed yet:
- Revert the file change.
- Create a new migration for your fix.
If you must change the file (e.g. it's the very last migration and only on your machine):
sqlx migrate revert(undoes the DB change)- Edit the file.
sqlx migrate run(re-applies and calculates new hash).
Scenario: Checksum Mismatch (Remote/Shared)
Do not force push.
- Accept that the "bad" migration is now canon.
- Create a new "fix-forward" migration.