Baseline
A common scenario is to have an existing database that you want to start managing with Emigrate. This is called baselining.
Baselining an existing database schema
Let’s assume you have a PostgreSQL database with the following schema:
CREATE TABLE public.users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());
CREATE TABLE public.posts ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES public.users(id), title VARCHAR(255) NOT NULL, body TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());Create a baseline migration
You can baseline this database by first creating a baseline migration (here we name it “baseline”):
npx emigrate new --plugin postgres baselinepnpm emigrate new --plugin postgres baselineyarn emigrate new --plugin postgres baselinebunx --bun emigrate new --plugin postgres baseline{ "scripts": { "emigrate": "emigrate" }, "dependencies": { "@emigrate/cli": "*" }}deno task emigrate new --plugin postgres baselineWhich will generate an empty migration file in your migration directory:
-- Migration: baselineYou can then add the SQL statements for your database schema to this migration file:
-- Migration: baselineCREATE TABLE public.users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());
CREATE TABLE public.posts ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES public.users(id), title VARCHAR(255) NOT NULL, body TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());Log the baseline migration
For new environments this baseline migration will automatically be run when you run emigrate up.
For any existing environments you will need to run emigrate up with the --no-execution flag to prevent the migration from being executed and only log the migration:
npx emigrate up --no-executionpnpm emigrate up --no-executionyarn emigrate up --no-executionbunx --bun emigrate up --no-execution{ "scripts": { "emigrate": "emigrate" }, "dependencies": { "@emigrate/cli": "*" }}deno task emigrate up --no-executionIn case you have already added more migration files to your migration directory you can limit the “up” command to just log the baseline migration by specifying the --to option:
npx emigrate up --no-execution --to 20240118123456789_baseline.sqlpnpm emigrate up --no-execution --to 20240118123456789_baseline.sqlyarn emigrate up --no-execution --to 20240118123456789_baseline.sqlbunx --bun emigrate up --no-execution --to 20240118123456789_baseline.sql{ "scripts": { "emigrate": "emigrate" }, "dependencies": { "@emigrate/cli": "*" }}deno task emigrate up --no-execution --to 20240118123456789_baseline.sqlVerify the baseline migration status
You can verify the status of the baseline migration by running the emigrate list command:
npx emigrate listpnpm emigrate listyarn emigrate listbunx --bun emigrate list{ "scripts": { "emigrate": "emigrate" }, "dependencies": { "@emigrate/cli": "*" }}deno task emigrate listWhich should output something like this:
Emigrate list v0.14.1 /your/project/path
✔ migrations/20240118123456789_baseline.sql (done)
1 done (1 total)Happy migrating!
You can now start adding new migrations to your migration directory and run emigrate up to apply them to your database.
Which should be part of your CD pipeline to ensure that your database schema is always up to date in each environment.