Migrations & Seeding
Migrations & Seeding
In development, synchronize: true auto-updates your schema — convenient but dangerous. In production you need migrations: versioned, reviewable scripts that change the database schema safely and reversibly. Paired with seeding (populating reference or test data), they give you full control over your database state.
Why migrations?
- Safe — explicit changes, no surprise column drops.
- Versioned — every schema change is committed to source control.
- Reversible — each migration has an
up(apply) and adown(roll back). - Repeatable — the same sequence runs identically on every environment.
Anatomy of a migration
A migration is a class with two methods. up() moves the schema forward; down() undoes it:
Generating and running migrations
TypeORM can generate a migration by diffing your entities against the current database — then you review it before applying:
up() and down(), especially for anything that drops or renames.
Seeding data
Seeding populates the database with initial data: reference tables (roles, categories), an admin user, or sample data for testing. A clean approach is a standalone script using the application context from the lifecycle lesson:
Migrations vs seeding
Keep them separate: migrations change the schema (structure), seeders insert data (content). Mixing data inserts into schema migrations makes both harder to reason about and to roll back.
Summary
Use migrations — versioned up/down scripts — for all production schema changes instead of synchronize. Generate them from entity diffs, but always review before running. Seed initial and reference data with idempotent scripts, ideally via the standalone application context. Keep schema (migrations) and data (seeders) concerns separate. Next: transactions, for changes that must all succeed or all fail.