Dependency Tracking
How pgmt ensures database objects are created, modified, and dropped in the correct order.
Why Dependency Tracking Matters
Section titled “Why Dependency Tracking Matters”Database objects often depend on each other. pgmt automatically tracks these dependencies to:
- Apply changes in the right order - Create schemas before tables, types before columns
- Handle drops safely - Drop views before tables, constraints before columns
- Prevent circular dependencies - Detect impossible dependency loops
- Generate correct migrations - Ensure production deployments succeed
Dependency Hierarchy
Section titled “Dependency Hierarchy”PostgreSQL enforces a natural hierarchy of database objects:
Typical creation order:
- Schemas (infrastructure)
- Extensions (capabilities)
- Custom types (ENUMs, domains)
- Tables (data structures)
- Views (queries)
- Functions (logic)
- Triggers (behavior)
How pgmt Tracks Dependencies
Section titled “How pgmt Tracks Dependencies”pgmt uses three methods to understand dependencies:
1. File Organization (Alphabetical)
Section titled “1. File Organization (Alphabetical)”Files are loaded alphabetically by default:
schema/├── 01_schemas/app.sql # Loaded first├── 02_types/status.sql # Loaded second├── 03_tables/users.sql # Loaded third└── 04_views/active_users.sql # Loaded last2. Explicit Dependencies (-- require:)
Section titled “2. Explicit Dependencies (-- require:)”Declare dependencies in your SQL files:
-- require: 01_schemas/app.sql, 02_types/user_status.sqlCREATE TABLE app.users ( id SERIAL PRIMARY KEY, status app.user_status DEFAULT 'active');3. Automatic Detection
Section titled “3. Automatic Detection”pgmt automatically detects:
- Schema references:
app.usersdepends onappschema - Type usage: Columns using custom types depend on those types
- Array types:
priority[]depends onprioritytype - Foreign keys: Tables with FKs depend on referenced tables
Common Dependency Patterns
Section titled “Common Dependency Patterns”Basic Hierarchy
Section titled “Basic Hierarchy”-- 1. Schemas created firstCREATE SCHEMA app;
-- 2. Types created secondCREATE TYPE app.user_status AS ENUM ('active', 'inactive');
-- 3. Tables created thirdCREATE TABLE app.users ( id SERIAL PRIMARY KEY, status app.user_status DEFAULT 'active');
-- 4. Views created lastCREATE VIEW app.active_users ASSELECT * FROM app.users WHERE status = 'active';Multiple Dependencies
Section titled “Multiple Dependencies”-- require: schemas/app.sql, types/order_status.sql, tables/users.sqlCREATE TABLE app.orders ( id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES app.users(id), status app.order_status DEFAULT 'pending');This table depends on:
- The
appschema (schema reference) - The
order_statustype (column type) - The
userstable (foreign key)
Organizing Files
Section titled “Organizing Files”You can organize your schema files however you want. Two common approaches:
Numbered prefixes leverage alphabetical loading:
schema/├── 01_schemas/app.sql├── 02_types/enums.sql├── 03_tables/users.sql├── 04_views/analytics.sqlFiles load in order, dependencies are implicit.
Explicit dependencies with -- require: comments:
-- require: schemas/app.sql, types/user_status.sql, tables/users.sqlCREATE VIEW app.user_dashboard ASSELECT u.id, u.email, u.status::text as status_displayFROM app.users u;File organization is flexible, dependencies are explicit.
Many projects use a mix: numbered prefixes for broad categories, -- require: for specific dependencies within categories.
Circular Dependencies
Section titled “Circular Dependencies”Your schema must be a directed acyclic graph (DAG) - no circular dependencies. If view A depends on view B which depends on view A, pgmt will detect the cycle and fail. The fix is to merge files or restructure to break the cycle.
Troubleshooting Dependencies
Section titled “Troubleshooting Dependencies”If pgmt baseline create or pgmt migrate new fails with dependency errors, use the debug command:
# View full dependency graphpgmt debug dependencies
# Check a specific objectpgmt debug dependencies --object public.orders
# Human-readable formatpgmt debug dependencies --format textCommon issues:
- Missing
-- require:headers - A file uses an object defined in another file that loads later alphabetically. Add explicit dependencies. - Circular dependencies - Restructure to break the cycle, or merge the interdependent objects into one file.
- Wrong file ordering - Numbered prefixes (01*, 02*) should match the dependency order.
How pgmt Uses Dependencies
Section titled “How pgmt Uses Dependencies”During pgmt apply
Section titled “During pgmt apply”- Load schema files in dependency order
- Build shadow database with properly ordered objects
- Compare to dev database
- Generate migration steps respecting dependencies
During pgmt migrate new
Section titled “During pgmt migrate new”- Analyze differences between catalogs
- Order CREATE operations forward (dependencies first)
- Order DROP operations reverse (dependents first)
- Handle ALTER operations considering dependencies
Example Migration Output
Section titled “Example Migration Output”-- Migration respects dependencies automaticallyCREATE SCHEMA app;CREATE TYPE app.status AS ENUM ('active', 'inactive');CREATE TABLE app.users ( id SERIAL PRIMARY KEY, status app.status DEFAULT 'active');CREATE VIEW app.active_users AS SELECT * FROM app.users WHERE status = 'active';No manual ordering needed - pgmt handles it automatically.
Related Concepts:
- How pgmt Works - The complete workflow
- Schema Organization - Advanced patterns and multi-file strategies
- Shadow Database - How dependency rules are validated