What are migrations and seeding?
A migration is a versioned, repeatable change to the database schema — adding a column, a table, an index. Seeding fills a database with sample data for development and testing. Together they make schema changes safe and reproducible across every environment.
Why it matters
Once an app has real data, you cannot just edit the schema by hand — you need controlled, reviewable changes that run identically in dev, staging, and production. Migrations give you that. Seeding gives every developer and CI run a consistent dataset to work against, which keeps the team productive.
What to learn
- Generating migrations from schema changes
- Running and rolling back migrations
- Keeping migrations in version control
- Backward-compatible (expand/contract) migrations
- Seeding scripts for dev and test data
- Migrations in CI/CD
- The danger of destructive migrations
Common pitfall
Running a destructive migration — dropping or renaming a column — in one step while old code still uses it, breaking production mid-deploy. Use the expand-then-contract pattern: add the new column, migrate code to it, then remove the old one in a later deploy. Never drop something the running code still reads.
Resources
Primary (free):
- Prisma — Migrate · docs
- Drizzle — Migrations · docs
- PostgreSQL — Schema changes · docs
Practice
Add a column to your schema and generate a migration, then run it and practice rolling it back. Write a seed script that populates a few related records for development. Plan how you would rename a column with expand/contract. Done when the schema change is a versioned migration, not a manual edit.
Outcomes
- Generate, run, and roll back migrations.
- Keep migrations versioned and in CI.
- Use expand/contract for safe schema changes.
- Seed consistent dev and test data.