Database Migration
Definition & meaning
Definition
A Database Migration is a versioned, incremental change to a database schema — creating tables, adding columns, modifying constraints, or transforming data. Migrations provide a controlled, repeatable way to evolve a database alongside application code, ensuring every environment (development, staging, production) has the same schema. Each migration is a file with an "up" function (apply the change) and optionally a "down" function (rollback), executed in sequential order. Migration tools track which migrations have been applied, preventing duplicate execution. Supabase provides a built-in migration system, while standalone tools include Prisma Migrate, Flyway, Alembic (Python), and golang-migrate. Best practices include never modifying applied migrations (create a new one instead), testing migrations on a staging database first, and keeping migrations small and focused.
How It Works
Database migration is the process of evolving a database schema over time through versioned, incremental change scripts. Each migration file contains an "up" operation (applying the change) and a "down" operation (reverting it), allowing teams to move forward and backward through schema versions. Migration tools track which migrations have been applied using a dedicated metadata table in the database itself. When you run migrations, the tool compares applied migrations against available files and executes only the pending ones in order. This ensures every environment — development, staging, production — can reproduce the exact same database schema by running the same migration sequence. Migrations handle operations like creating tables, adding columns, modifying indexes, renaming fields, and transforming existing data. The critical rule is that migrations in production must be additive and backward-compatible: never drop a column that running code depends on. Instead, you deploy code that stops using the column first, then migrate to remove it. This two-phase approach prevents downtime during deployments.
Why It Matters
Database migrations bring version control discipline to your data layer. Without them, schema changes are ad-hoc SQL scripts run manually — a recipe for inconsistencies between environments, lost changes, and deployment failures. For developers working in teams, migrations ensure everyone's local database stays in sync and that CI/CD pipelines can spin up test databases with the correct schema. For decision-makers, proper migration practices reduce deployment risk and enable confident rollbacks when issues arise. Migrations also create an audit trail of every schema change, who made it, and when — essential for debugging data issues and maintaining compliance. Getting migrations wrong in production can cause data loss or extended outages.
Real-World Examples
Prisma Migrate is popular in the Node.js/TypeScript ecosystem, generating migrations from schema changes defined in the Prisma schema file. Supabase provides a migration system through its CLI and also tracks migrations in the dashboard — at ThePlanetTools.ai, we use Supabase migrations to manage our glossary and review database schemas. Rails' ActiveRecord Migrations pioneered the convention and remain a gold standard for developer experience. Flyway and Liquibase dominate the Java ecosystem. Django's migration system auto-detects model changes and generates migration files. For raw SQL migrations, tools like golang-migrate and dbmate provide language-agnostic migration management. Knex.js offers migration support for Node.js applications working directly with SQL. TypeORM and Drizzle ORM are newer TypeScript options that generate type-safe migrations.