Skip to main content
pgschema supports ignoring specific database objects using a .pgschemaignore file, enabling gradual onboarding and selective schema management.

Overview

The .pgschemaignore file allows you to exclude database objects from pgschema operations. This is particularly useful when:
  1. Gradual Migration - Incrementally adopt pgschema without managing all existing objects
  2. Temporary Objects - Exclude temp tables, debug views, and development-only objects
  3. Legacy Objects - Ignore deprecated objects while maintaining new schema management
  4. Environment-Specific Objects - Skip objects that exist only in certain environments
  5. Role-Specific Privileges - Ignore grants to roles that don’t exist in the plan database

File Format

The .pgschemaignore file is automatically loaded when present in the current directory:
Create a .pgschemaignore file in your project directory using TOML format:

Pattern Syntax

Wildcard Patterns

Use * to match any sequence of characters:

Exact Patterns

Specify exact object names without wildcards:

Negation Patterns

Use ! prefix to exclude objects from broader patterns:
This will ignore test_data, test_results but keep test_core_config, test_core_settings.

Privileges

The [privileges] and [default_privileges] sections filter GRANT statements by grantee role name. This is useful when running pgschema plan with roles that don’t exist in the plan database, or managing migrations across environments with different role configurations.
The [privileges] section filters explicit grants (GRANT ... TO role), including column-level privileges. The [default_privileges] section filters ALTER DEFAULT PRIVILEGES statements.

Constraints

The [constraints] section matches table constraints by constraint name (primary keys, unique, foreign keys, check, and exclusion constraints). When a constraint is ignored, pgschema neither creates, drops, nor reports drift on it — it is left entirely to be managed out-of-band.
This is useful when:
  1. Out-of-band constraints - A constraint is added and managed manually (e.g. disabled during an AWS DMS migration and re-added afterward), and you don’t want pgschema plan to flag it for drop.
  2. Cross-schema foreign keys - Prefer ignoring the referenced schema or table (see below) so plan can stub it. Alternatively, omit the FK from the desired SQL and ignore the live constraint by name so each schema can be bootstrapped independently.
Patterns match the constraint name only, which is not necessarily unique across tables. Be careful with broad patterns like *, as ignoring a primary key or unique constraint can leave a table without the keys it needs.

Schemas and Cross-Schema Foreign Keys

The [schemas] section matches schema names. Combined with schema-qualified [tables] patterns (auth.users, auth.*), this is the way to keep a foreign key to an unmanaged schema (for example Supabase auth.users) in your desired SQL.
When plan applies this SQL to its temporary database, it clones a structural stub of each ignored FK target from the target database (columns plus PRIMARY KEY / UNIQUE constraints), so PostgreSQL can create the foreign key. You do not need a manual CREATE TABLE auth.users stub in your schema file or a separate external plan database for this case. The auto-stub is not part of the managed schema: dump does not emit auth.users, and plan will not create or drop it. The referenced table must already exist on the target database. If it does not, use a manual stub in your schema file or an external plan database.
Cross-schema table patterns must be schema-qualified (auth.users or auth.*). A bare pattern like users only matches tables in the schema you are managing, so it will not stub auth.users.

Triggers

The [triggers] section matches triggers by trigger name. When a trigger is ignored, pgschema neither creates, drops, nor reports drift on it — it is left entirely to be managed out-of-band.
This is useful when an extension automatically creates triggers on tables you manage. For example, the pgai vectorizer adds _vectorizer_src_trg_* triggers to source tables; ignoring them keeps pgschema plan from flagging them for drop while you continue to manage the rest of the table.
Patterns match the trigger name only, which is not necessarily unique across tables. Be careful with broad patterns like *.

Triggers on Ignored Tables

Triggers can be defined on ignored tables. The table structure is not managed, but the trigger itself is.
The trigger will be managed while external_users table structure remains unmanaged.