generate
Thegenerate command compares your current and desired schemas and produces golang-migrate compatible migration files. It automatically orders operations based on dependencies and generates both up and down migrations.
Usage
Flags
| Flag | Description | Default |
|---|---|---|
--current | Path to current schema JSON file (from extract) | Required |
--desired | Path to desired schema SQL file or directory | Required |
--output-dir | Output directory for migration files | ./migrations |
--preview | Preview migrations without writing files | false |
--start-version | Starting version number | Auto-detect |
--help, -h | Help for generate |
Examples
Basic Generation
Preview Mode
Preview what migrations would be created without writing files:Custom Starting Version
Docker
Output Files
Generated migration files follow the golang-migrate naming convention:File Format
Each migration file includes:- Header with metadata (timestamp, description)
- List of changes included
- Transaction control (
BEGIN/COMMIT) - Idempotent DDL statements
Idempotent DDL
All generated DDL statements are idempotent by default:| Statement Type | Idempotent Form |
|---|---|
| CREATE TABLE | CREATE TABLE IF NOT EXISTS |
| DROP TABLE | DROP TABLE IF EXISTS |
| CREATE INDEX | CREATE INDEX IF NOT EXISTS |
| DROP INDEX | DROP INDEX IF EXISTS |
| CREATE EXTENSION | CREATE EXTENSION IF NOT EXISTS |
| DROP EXTENSION | DROP EXTENSION IF EXISTS |
Transaction Control
pgtofu wraps migrations in transactions when safe:| Operation | Transaction |
|---|---|
| DDL statements | Yes |
| CREATE INDEX CONCURRENTLY | No (cannot run in transaction) |
| TimescaleDB operations | Depends on operation |
Change Ordering
pgtofu automatically orders operations based on dependencies:- Extensions - Must be created first
- Custom Types - Enums, composites, domains
- Sequences - Before tables that use them
- Tables - In dependency order (referenced tables first)
- Constraints - After tables exist
- Indexes - After tables exist
- Views - After tables they reference
- Functions - After types and tables they use
- Triggers - After functions and tables
- TimescaleDB - Hypertables, policies, continuous aggregates
Version Auto-Detection
When--start-version is not specified, pgtofu scans the output directory for existing migration files and continues from the next version:
Preview Mode
Use--preview to see what would be generated without writing files:
Handling Breaking Changes
When breaking changes are detected, pgtofu:- Includes a warning comment in the migration
- Generates the DDL but marks it as requiring review
- Displays a summary of breaking changes
Troubleshooting
No migrations generated
No migrations generated
If no changes are detected:
- Run
pgtofu difffirst to verify changes exist - Check that schema names match (default:
public)
Circular dependency error
Circular dependency error
This usually indicates a design issue in your schema:
- Check for circular foreign key references
- Consider using deferrable constraints
Permission denied writing files
Permission denied writing files
Ensure the output directory is writable:
Applying Migrations
Use golang-migrate to apply generated migrations:See Also
extract- Extract current database schemadiff- Preview changes before generating- Dependency Resolution - How operations are ordered
- CI/CD Integration - Automate migration generation