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.

Coverage Matrix

What each extractor handles today. Anything outside this matrix produces an ExtractionWarning and counts as unanalyzable in the coverage line.

ORMSurfaceCoverage
TypeORMqueryRunner.query() with literal SQLFull
TypeORMBuilder API (createTable, addColumn, etc.)Not transpiled, emits warning
Knexknex.raw() / trx.raw() with literal SQLFull
KnexSchema builder (table-level operations listed below)Focused subset; rest emits warning
SequelizequeryInterface.sequelize.query() with literal SQLFull
SequelizeBuilder API (queryInterface methods listed below)Focused subset; rest emits warning
Prismaprisma/migrations/**/migration.sqlFull (read as raw SQL)
Drizzledrizzle/*.sql generated filesFull (read as raw SQL)

Dynamic SQL (template literals with runtime interpolations, conditional builders, computed identifiers) is never silently treated as analyzed. The coverage line on every report tells you how many statements were extracted vs how many were dynamic.

TypeORM

bash
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

bash
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, createTableIfNotExists
  • alterTable, table (alias for alterTable)
  • dropTable, dropTableIfExists
  • renameTable, renameColumn, dropColumn, dropColumns
  • setNullable and dropNullable for 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') and onUpdate(...), when table and column names resolve cleanly
  • Timestamps: t.timestamps() produces created_at and updated_at columns

Anything not in the bullet lists above is not transpiled. Unsupported builder chains and dynamic patterns surface as ExtractionWarnings and count as unanalyzable in the coverage line, never as silently-passed.

Sequelize

bash
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, renameTable
  • addColumn, removeColumn, changeColumn, renameColumn
  • addIndex, removeIndex
  • addConstraint (UNIQUE, FOREIGN KEY, CHECK), removeConstraint

Volatile default detection

Sequelize.literal('clock_timestamp()') used as a defaultValue is lowered to a synthetic volatile expression so the normal analyzer can flag it like any other volatile default.

Prisma

bash
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

bash
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

bash
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.