v0.27.7

PostgreSQL
schema-as-code

Define schemas in native SQL. Diff against live databases. Apply migrations safely. No DSLs, no ORMs, just SQL.

terminal
$ pgmold plan -s sql:schema.sql -d postgres://localhost/mydb

-- Migration Plan (3 operations)

ALTER TABLE "public"."users"
  ADD COLUMN "email" TEXT NOT NULL;

CREATE INDEX "users_email_idx"
  ON "public"."users" ("email");

CREATE POLICY "users_read_own"
  ON "public"."users"
  FOR SELECT USING (auth.uid() = id);

How it works

Three steps. No migration files to manage. No state to track.

1

Define

Write your schema in plain SQL files. Tables, indexes, functions, policies — everything in native PostgreSQL DDL.

CREATE TABLE users (
  id UUID PRIMARY KEY,
  email TEXT NOT NULL,
  created_at TIMESTAMP
);
2

Diff

pgmold introspects your live database, compares it to your SQL files, and computes the exact delta.

$ pgmold plan \
  -s sql:schema.sql \
  -d postgres://localhost/db

+ ADD COLUMN "email"
+ CREATE INDEX
- DROP COLUMN "legacy"
3

Apply

Apply the migration in a single transaction. Destructive operations are blocked unless you explicitly opt in.

$ pgmold apply \
  -s sql:schema.sql \
  -d postgres://localhost/db

Applied 2 operations
-- 1 blocked (destructive)

Features

Everything you need to manage PostgreSQL schemas declaratively.

Native SQL

No HCL, no YAML, no DSLs. Write standard PostgreSQL DDL. If Postgres accepts it, pgmold understands it.

Drift detection

SHA256 fingerprint comparison catches manual schema changes. Use in CI to prevent drift.

Safety linting

Destructive operations are blocked by default. Lock hazard warnings prevent downtime. Production mode blocks table drops entirely.

RLS policies

Row-Level Security policies are first-class citizens. Define, diff, and apply policies alongside your tables.

Multi-schema

Manage auth, api, public, and custom schemas. Cross-schema foreign keys handled automatically.

CI/CD ready

GitHub Action included. JSON output for pipelines. Non-zero exit on drift. PR comments with migration plans.

Transactional apply

All migrations run in a single transaction. If anything fails, nothing changes. Atomic by default.

Partitioned tables

Full support for PARTITION BY and PARTITION OF syntax. Range, list, and hash partitioning.

ORM integration

Use Drizzle ORM schemas as source. Mix SQL and ORM sources. Bring your own schema format.

How pgmold compares

Focused on PostgreSQL. No compromises.

Feature pgmold Atlas pg-schema-diff Flyway
Schema format Native SQL HCL / SQL SQL SQL migrations
Approach Declarative Declarative Declarative Versioned
Drift detection
Lock hazard warnings
Safety linting
RLS policies
Terraform provider
Runtime Single binary Go binary Go library JVM

Get started

Install with Cargo and start managing your schemas in under a minute.

install
$ cargo install pgmold

# or from source
$ cargo install --git https://github.com/fmguerreiro/pgmold
usage
# See what would change
$ pgmold plan -s sql:schema.sql -d postgres://localhost/mydb

# Apply the migration
$ pgmold apply -s sql:schema.sql -d postgres://localhost/mydb

# Detect drift in CI
$ pgmold drift -s sql:schema.sql -d postgres://localhost/mydb --json

# Dump live database to SQL
$ pgmold dump -d postgres://localhost/mydb -o schema.sql

CI/CD in one step

Add schema checks to your GitHub Actions workflow. Drift detection, migration plan comments, and auto-labeling.

.github/workflows/schema-check.yml
name: Schema Check
on: pull_request

jobs:
  schema-ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: fmguerreiro/pgmold/.github/actions/drift-check@main
        with:
          schema: sql:schema/
          database: db:${{ secrets.DATABASE_URL }}
          target-schemas: public,auth

Terraform provider

Manage PostgreSQL schemas as infrastructure. pgmold diffs against the live database and applies only the necessary migrations on each terraform apply.

  • Declarative schema management in HCL
  • Automatic migration generation
  • Safety controls for destructive operations
  • Multi-schema support
main.tf
resource "pgmold_schema" "app" {
  schema_file       = "schema.sql"
  database_url      = var.database_url
  allow_destructive = false
}