Quick Start
Get started with pgmt in 10 minutes and see what makes it different from other migration tools.
Install pgmt
Section titled “Install pgmt”cargo install pgmtDon’t have Rust? Install it first:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shsource ~/.cargo/envVerify installation:
pgmt --versionSetup Database
Section titled “Setup Database”pgmt requires PostgreSQL 13 or later. Choose your preferred option:
Docker (Recommended):
docker run -d \ --name pgmt-dev \ -e POSTGRES_PASSWORD=dev \ -e POSTGRES_DB=myapp_dev \ -p 5432:5432 \ postgres:15Already have PostgreSQL? Just create a database:
createdb myapp_devInitialize Project
Section titled “Initialize Project”# Create project directorymkdir my-app && cd my-app
# Initialize pgmt (Docker users)pgmt init --dev-url postgres://postgres:dev@localhost/myapp_dev --defaults
# For local PostgreSQL without password# pgmt init --dev-url postgres://localhost/myapp_dev --defaultsThis creates:
my-app/├── schema/ # Your SQL schema files├── migrations/ # Generated migration files├── schema_baselines/ # Baseline snapshots (created on-demand)└── pgmt.yaml # ConfigurationWant more control? Run pgmt init without --defaults for an interactive setup that:
- Shows you exactly what’s in your database (if importing existing schema)
- Lets you configure which object types to manage (comments, grants, triggers, extensions)
- Automatically validates generated schema files
- Provides clear guidance if dependency issues are found
Create Your First Schema
Section titled “Create Your First Schema”Create a simple table:
cat > schema/users.sql << 'EOF'CREATE TABLE users ( id SERIAL PRIMARY KEY, email TEXT NOT NULL, full_name TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW());EOFNow add a view that depends on it:
cat > schema/active_users.sql << 'EOF'-- require: users.sqlCREATE VIEW active_users ASSELECT * FROM users;EOFNotice the -- require: users.sql? This is like import in Python or require in Node.js - it declares dependencies and lets you organize your schema however makes sense for your project.
Apply the schema to your dev database:
pgmt applypgmt will:
- Create a shadow database
- Load your schema files in dependency order
- Compare with your dev database
- Apply the necessary changes
Automatic Dependency Tracking
Section titled “Automatic Dependency Tracking”Here’s what makes pgmt special. Let’s rename a column in the base table:
cat > schema/users.sql << 'EOF'CREATE TABLE users ( id SERIAL PRIMARY KEY, email TEXT NOT NULL, name TEXT NOT NULL, -- Renamed from full_name created_at TIMESTAMP DEFAULT NOW());EOFNow apply the change:
pgmt applyWhat just happened?
pgmt automatically:
- Dropped the
active_usersview (because the column structure changed) - Renamed the column:
ALTER TABLE users RENAME COLUMN full_name TO name - Recreated the
active_usersview with the same definition
The view file didn’t change - it still says SELECT * FROM users - but pgmt knows it needs to be recreated because the underlying table structure changed.
Make It More Complex
Section titled “Make It More Complex”Let’s add another view that depends on the first one:
cat > schema/recent_users.sql << 'EOF'-- require: active_users.sqlCREATE VIEW recent_users ASSELECT * FROM active_usersWHERE created_at > NOW() - INTERVAL '7 days';EOFApply it:
pgmt applyNow update the active_users view definition to add a filter:
cat > schema/active_users.sql << 'EOF'-- require: users.sqlCREATE VIEW active_users ASSELECT * FROM users WHERE email IS NOT NULL; -- Added filterEOFApply again:
pgmt applypgmt automatically:
- Dropped
recent_users(depends on active_users) - Dropped
active_users(the view we’re changing) - Created
active_users(new definition with filter) - Created
recent_users(unchanged, but depends on active_users)
All in the correct order, based on the dependency graph.
Why This Matters
Section titled “Why This Matters”With traditional migration tools, you’d manually write:
-- Hope you remember all the dependencies!DROP VIEW recent_users;DROP VIEW active_users;CREATE VIEW active_users AS ...; -- Better get the order rightCREATE VIEW recent_users AS ...;With pgmt, you edit views and functions like source code. pgmt handles the drop/recreate mechanics, figures out the dependency cascade, and applies changes in the correct order. No manual migration scripts needed.
Schema Organization
Section titled “Schema Organization”The -- require: statements aren’t just for dependency resolution - they’re for organizing your schema like a real programming language:
schema/├── 01_foundation/│ └── extensions.sql # PostgreSQL extensions├── 02_core/│ ├── users.sql # Core entities│ └── posts.sql # require: users.sql└── 03_features/ └── analytics.sql # require: users.sql, posts.sqlOrganize by domain, by feature, by team ownership - whatever makes sense for YOUR project. pgmt handles the dependency graph automatically.
Generate Production Migration
Section titled “Generate Production Migration”When you’re ready to deploy to production, generate an explicit migration:
pgmt migrate new "initial schema with user views"This creates a migration file like:
migrations/V1734567890__initial_schema_with_user_views.sqlReview the generated SQL:
cat migrations/V*__initial_schema_with_user_views.sqlYou’ll see explicit SQL statements that you can review, test, and version control before deploying to production.
Pro Tips
Section titled “Pro Tips”Watch Mode for Active Development
Section titled “Watch Mode for Active Development”pgmt apply --watchAutomatically applies safe changes as you edit schema files. Prompts for confirmation on destructive operations (like dropping columns).
Preview Changes Before Applying
Section titled “Preview Changes Before Applying”pgmt apply --dry-runSee what would change without actually applying it.
Check Migration Status
Section titled “Check Migration Status”pgmt migrate statusSee which migrations have been applied to your database.
Next Steps
Section titled “Next Steps”Learn the Workflow
Section titled “Learn the Workflow”Organize your schema:
- Schema Organization Guide - Multi-file patterns,
-- require:best practices
Work with a team:
- Team Collaboration - Merge conflicts, code review, branching strategies
Handle complex changes:
- Migration Strategies - Destructive changes, data migrations, rollbacks
Have an Existing Database?
Section titled “Have an Existing Database?”- Adopt Existing Database - Import existing schema, create baselines, team onboarding
Reference & Support
Section titled “Reference & Support”- CLI Reference - All commands and options
- Configuration Guide - Customize pgmt for your environment
- PostgreSQL Features - Complete list of supported database objects
- Troubleshooting - Common issues and solutions