From foreign-key cycles to a table migration plan
A child table depends on its referenced parent. A dependency DAG can be ordered with parents first for creation and children first for drop. Mutual references create strongly connected groups that have no such order while all foreign keys remain inline. This planner lists all inter-table relationships inside those groups for later addition. Manually omit those constraints, create tables in the displayed order, then add the listed constraints. Separate ALTER additions also run in that later phase. The drop plan removes cycle constraints first and then reverses the remaining dependencies.
A DEFERRABLE constraint may help with transaction-time data loading when its checks can be postponed. It does not fix schema-creation order. NOT VALID and referential actions remain visible as review evidence; this tool neither loads data nor decides whether a constraint can safely be deferred. A self-reference can stay in table creation but still deserves a data-loading review.
Supported PostgreSQL DDL subset
Supports PostgreSQL 16–18 structural forms: explicit-column CREATE TABLE, optional UNLOGGED and IF NOT EXISTS, inline REFERENCES as the last column constraint, named or unnamed table FOREIGN KEY, composite columns, schema-qualified names, and single ALTER TABLE [ONLY] ADD [CONSTRAINT name] FOREIGN KEY statements. Common MATCH SIMPLE/FULL, ON DELETE/UPDATE NO ACTION/RESTRICT/CASCADE/SET NULL/SET DEFAULT, DEFERRABLE, NOT DEFERRABLE, INITIALLY IMMEDIATE/DEFERRED and ALTER NOT VALID are retained. Omitted referenced columns resolve to a supplied declared primary key. Unquoted identifiers fold ASCII letters to lowercase; double quotes preserve case. Nested block comments, line comments, standard single-quoted strings (standard_conforming_strings enabled), E strings and dollar-quoted strings are tokenized without creating false dependencies.
Primary-key column declarations are inventoried. Ordinary data types, defaults, UNIQUE, CHECK and EXCLUDE expressions are not semantically validated. Inputs must be valid PostgreSQL DDL within the subset: this is a structural parser, not a replacement for the database parser. Duplicate table identities, undeclared key columns, missing referenced tables, malformed foreign-key clauses and unsupported statements block order generation. Lexical errors stop analysis. A final statement may omit its semicolon.
Unsupported: MySQL/backtick and SQL Server/bracket quoting, temporary tables and their session-schema visibility, arrays, CREATE AS/LIKE, inheritance, partitions, CREATE suffix/storage clauses, action column subsets, multiple ALTER actions, other ALTER operations, schema/search-path statements, views, indexes, triggers, sequences, functions, procedural scripts, psql commands and dynamic SQL. These require a complete target-database dependency review. Non-ASCII identifier folding and custom PostgreSQL identifier-length builds are outside the supported assumptions. No live catalog, database credentials or schema uploads are needed.
Export a reviewable migration order
JSON preserves version, format assumptions, file sizes, table identities, columns, source lines, foreign-key options, cyclic groups, findings and phased orders. Formula-safe CSV includes the full inventory regardless of UI filters. The text manifest describes the manual creation/addition/removal/drop steps. SVG provides a bounded dependency overview; HTML and browser Print / PDF combine the manifest and full evidence. Reports can contain schema names, filenames and original foreign-key clauses, so review them before sharing.
Frequently asked questions
Does my SQL leave the browser?
No. SQL files and pasted text are processed in a cancellable local Web Worker. No database connection is opened and no statements are executed. Clear removes the inputs and results from this tab.
Can DEFERRABLE solve a table-creation cycle?
No. In PostgreSQL, DEFERRABLE controls when data constraints are checked within a transaction. A referenced table must still exist. For mutual table dependencies, manually omit the listed foreign keys from CREATE TABLE and add them after every table exists.
Why is a self-reference shown as a cycle?
A table that references itself forms a one-node cyclic component. PostgreSQL supports that relationship during table creation and drop. It can still complicate data loading; review nullable staging, insert order or appropriate deferrable data checks in the target database.
Are the exported orders executable migration scripts?
No. They are review manifests with explicit assumptions and source evidence. No SQL is rewritten. Review original DDL, actual constraint names, key uniqueness, data types, schemas, other dependencies and target-version behavior in an isolated PostgreSQL database.
What happens when a referenced table is missing?
The relationship remains visible with its source file and line. Creation/drop plans are blocked because the missing table and its prerequisites cannot be ordered from this input. Supply a complete schema subset and resolve every finding.
PostgreSQL references
Verify syntax and behavior with the official CREATE TABLE reference, ALTER TABLE reference and SET CONSTRAINTS reference. Check your target version and actual catalog dependencies before applying a migration.