What Are Database Migrations?
Learn how database migrations help you safely change your app's database structure over time — without losing data or breaking things.
Version Control for Your Database
Imagine you built a website with a users table. Six months later, you need to add a phone number field. How do you make that change safely? That's where database migrations come in.
A database migration is a file that describes a change you want to make to your database — like adding a new column, creating a new table, or fixing a typo in a field name. Instead of changing the database directly by hand, you write a migration file, and a tool applies it step by step.
Think of it like Git, but for your database structure. Every change is tracked, reversible, and shareable with your whole team.
Making Changes Without Chaos
Without migrations, a team of developers making direct changes to the database is like everyone editing the same document at once — things get overwritten, conflicts happen, and sometimes data disappears.
Migrations solve this by giving every developer a clear, ordered list of changes to apply. When a new teammate joins, they run all migrations from the start and their database is identical to everyone else's. When you deploy to a new server, the same migrations run the same way.
It also means you can undo a bad change. Made a mistake? Run the down migration and your database goes back to how it was before.
💡 Key Insight
Database migrations let you treat your database like code — you can review changes before applying them, undo them if something goes wrong, and make sure every environment (dev, staging, production) ends up in the same state.
The Migration Workflow
Here's how migrations work in practice:
Most tools (like Django's migrate, Rails migrations, or Prisma) also keep a table inside your database that tracks which migrations have already run. That way, if you deploy to a new server, it only runs the ones that haven't been applied yet.
Adding a Column to a Table
Let's say you want to add an email field to your users table. In SQL, your migration might look like this:
-- Add a new email column to the users table ALTER TABLE users ADD COLUMN email VARCHAR(255); -- Make sure every existing row has an email UPDATE users SET email = 'temp@example.com' WHERE email IS NULL; -- Now require the field so no new rows can skip it ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Three steps, all bundled in one migration. If something goes wrong, the rollback reverses all three steps in reverse order.
Most frameworks let you write migrations in their preferred language (Python, Ruby, JavaScript) instead of raw SQL, which makes them easier to read and less error-prone.
Knowledge Check
Test what you learned with this quick quiz.