ORM Migrations
For code-based ORMs, pgfence extracts or transpiles SQL from the forward migration path only. Prisma and Drizzle support means reading their generated .sql files directly, not parsing the schema DSL itself.
TypeORM
pgfence analyze --format typeorm src/migrations/*.ts pgfence extracts literal queryRunner.query() calls from the up() method. The parameter name is resolved dynamically, so queryRunner, qr, or any other identifier works.
Auto-commit detection
When a migration sets public transaction = false, pgfence detects auto-commit mode and skips compounding lock warnings (each statement releases its lock before the next begins).
Builder API detection
TypeORM also offers a builder API such as queryRunner.createTable() and queryRunner.addColumn(). The current OSS extractor does not transpile that API to SQL. Instead, it emits an ExtractionWarning naming the specific method so the migration is never silently treated as fully analyzed.
Knex
pgfence analyze --format knex migrations/*.ts pgfence extracts literal knex.raw() / trx.raw() calls and transpiles a focused subset of schema builder calls from the up export into SQL for analysis.
Schema builder support
The current transpiler covers common table-level operations such as:
createTable,createTableIfNotExistsalterTable,table(alias for alterTable)dropTable,dropTableIfExistsrenameTable,renameColumn,dropColumn,dropColumnssetNullableanddropNullablefor NOT NULL changes
Column builder support
Inside createTable and alterTable callbacks, pgfence handles common column definitions including:
- Column types:
integer,bigInteger,text,string,float,decimal,boolean,date,datetime,timestamp,binary,json,jsonb,uuid,specificType - Modifiers:
notNullable(),nullable(),defaultTo(),primary(),unique() - Foreign keys: basic literal chains such as
references('id').inTable('users').onDelete('CASCADE')andonUpdate(...), when table and column names resolve cleanly - Timestamps:
t.timestamps()producescreated_atandupdated_atcolumns
Many unsupported dynamic patterns are surfaced as ExtractionWarnings, but some ORM builder chains are still best-effort and only partially reconstructed. Treat the coverage line as a lower bound on what was analyzed, not proof that every ORM statement was fully recovered.
Sequelize
pgfence analyze --format sequelize migrations/*.js pgfence extracts literal queryInterface.sequelize.query() calls from the up() function and transpiles a focused subset of queryInterface builder calls into SQL.
Builder API support
The current transpiler covers common queryInterface methods:
createTable,dropTable,renameTableaddColumn,removeColumn,changeColumn,renameColumnaddIndex,removeIndexaddConstraint(UNIQUE, FOREIGN KEY, CHECK),removeConstraint
Volatile default detection
Sequelize.literal('NOW()') used as a defaultValue is lowered to a synthetic volatile expression so the normal analyzer can flag it like any other non-constant default.
Prisma
pgfence analyze --format prisma prisma/migrations/**/migration.sql Prisma generates plain .sql files in its migrations directory. pgfence reads those files directly, the same way it reads raw SQL migrations.
Drizzle
pgfence analyze --format drizzle drizzle/*.sql Drizzle also generates plain .sql migration files. pgfence reads those directly, the same way it reads raw SQL migrations.
Auto-Detect
pgfence analyze migrations/* Auto-detect uses both file paths and source markers. Prisma migrations are detected from the prisma/migrations path, Drizzle from a drizzle/ path, and .ts / .js files are checked for TypeORM, Knex, or Sequelize markers in the source.
Dynamic SQL
Extractors that encounter template literals with interpolations or other non-literal arguments emit an ExtractionWarning. When pgfence cannot fully reconstruct a statement, the coverage line tells you how much of the migration was not statically analyzable.