Tools & Infrastructure

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.

Scroll to start

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:

The Migration Workflow
📝
Write
You create a migration file with the change you want
🔍
Review
You or a teammate reviews the change
⚙️
Run
The migration tool applies the change to the database
Track
It's recorded so it never runs again by accident
repeat for every change

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:

001_add_email_to_users.sql
-- 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.

Quick Quiz — 3 Questions

Question 1
What is a database migration?
Question 2
Why do migrations help teams work on the same database?
Question 3
What does a "down" or rollback migration do?
🏆

You crushed it!

Perfect score on this module.