PostgreSQL Database Migration Management Tool
node-pg-migrate is a robust and feature-rich PostgreSQL database migration management tool designed for Node.js environments. It empowers developers to manage schema changes through JavaScript or TypeScript migration files, offering precise control over `up` and `down` operations for evolving database schemas. The current stable version is 8.0.4, with active development proceeding on the v9.0.0 alpha series, indicating a future major release that will introduce significant enhancements and breaking changes. The project generally maintains a consistent release cadence for minor and patch versions, while major updates are developed over a longer period. Key advantages include its strong TypeScript support, a flexible and extensible migration file structure, and a comprehensive command-line interface, all contributing to streamlined and reliable database schema evolution. It integrates natively with the `pg` client library for database interactions.
Common errors
-
Error: Cannot find module 'node-pg-migrate'
cause The 'node-pg-migrate' package is not installed or not accessible in the current project environment.fixRun `npm install node-pg-migrate pg` or `yarn add node-pg-migrate pg` to install the package and its peer dependency. -
Error: connect ECONNREFUSED
cause The PostgreSQL database server is either not running, or the connection string/details (host, port, credentials) are incorrect.fixVerify that your PostgreSQL server is operational and accessible. Double-check your `DATABASE_URL` environment variable or connection configuration for accuracy, including host, port, username, and password. -
ReferenceError: require is not defined in ES module scope
cause You are attempting to use CommonJS `require()` syntax in an ES module (`.mjs` or `"type": "module"` in `package.json`) for a package that is primarily designed for ESM or ships ESM types.fixRefactor your imports to use ES module syntax (e.g., `import { migrate } from 'node-pg-migrate';`). If using TypeScript, ensure your `tsconfig.json` `module` and `moduleResolution` settings are appropriate for ESM. -
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for ...
cause Node.js cannot directly execute TypeScript migration files (`.ts`) without a transpiler or loader in place (e.g., `ts-node`, `tsx`).fixUse a runtime TypeScript executor like `ts-node` (`npx ts-node your-script.ts`) or `tsx` (`npx tsx your-script.ts`). Alternatively, compile your TypeScript migration files to JavaScript before running.
Warnings
- breaking Version 9.x (currently in alpha) will introduce significant breaking changes, including revised migration loading strategies and potential adjustments to the programmatic API. Users upgrading from v8.x should carefully consult the v9 release notes and migration guides to understand necessary code adaptations.
- gotcha node-pg-migrate v8.x has a strict peer dependency on `pg` version `>=4.3.0 <9.0.0`. Using `pg` v9.x or newer with `node-pg-migrate` v8.x will lead to compatibility issues, potentially causing errors or preventing migrations from executing.
- gotcha Version 8.x of node-pg-migrate requires Node.js `v20.11.0` or higher. Running on older Node.js versions will result in errors due to unsupported syntax or missing runtime features.
- breaking Version 8.0.4 includes a critical security fix related to the `glob` dependency. Prior versions may be vulnerable to specific path traversal or denial-of-service issues.
Install
-
npm install node-pg-migrate -
yarn add node-pg-migrate -
pnpm add node-pg-migrate
Imports
- migrate
const migrate = require('node-pg-migrate');import { migrate } from 'node-pg-migrate'; - PgLiteral
import type { PgLiteral } from 'node-pg-migrate';import { PgLiteral } from 'node-pg-migrate'; - MigrationBuilder
import { MigrationBuilder } from 'node-pg-migrate';import type { MigrationBuilder, ColumnDefinitions } from 'node-pg-migrate';
Quickstart
import { migrate } from 'node-pg-migrate';
import { Pool } from 'pg';
import path from 'path';
import 'dotenv/config'; // Make sure to install dotenv if you use it
// --- IMPORTANT: Ensure DATABASE_URL is set in your .env file or environment variables ---
// Example: DATABASE_URL=postgres://user:password@localhost:5432/testdb
async function runDatabaseMigrations() {
const databaseUrl = process.env.DATABASE_URL ?? 'postgres://user:password@localhost:5432/testdb';
if (!databaseUrl) {
console.error('DATABASE_URL environment variable is not set. Please provide it.');
process.exit(1);
}
const pool = new Pool({
connectionString: databaseUrl,
});
const migrationsDir = path.resolve(__dirname, 'migrations');
try {
console.log('Starting database migrations...');
await migrate({
db: pool, // Pass the pg.Pool instance
migrationsTable: 'pgmigrations', // Table to track applied migrations
dir: migrationsDir, // Directory containing your migration files
direction: 'up', // 'up' to apply, 'down' to revert
count: Infinity, // Apply all pending migrations
createShorthands: true, // Automatically create shorthand definitions
// verbose: true, // Uncomment for detailed logging
log: (message: string) => console.log(`[node-pg-migrate] ${message}`),
noLock: false, // Use advisory locks to prevent concurrent migrations
dryRun: false // Set to true to preview changes without applying
});
console.log('Database migrations completed successfully.');
} catch (error) {
console.error('Database migration failed:', error);
process.exit(1);
} finally {
await pool.end();
}
}
runDatabaseMigrations();
// To run this:
// 1. npm install node-pg-migrate pg dotenv
// 2. Create a 'migrations' directory.
// 3. Create a migration file, e.g., 'migrations/001_initial_schema.ts':
// import type { MigrationBuilder, ColumnDefinitions } from 'node-pg-migrate';
// export async function up(pgm: MigrationBuilder): Promise<void> {
// pgm.createTable('users', { id: 'id', name: { type: 'varchar(100)', notNull: true } });
// }
// export async function down(pgm: MigrationBuilder): Promise<void> {
// pgm.dropTable('users');
// }
// 4. Configure DATABASE_URL in a .env file.
// 5. Run with `npx ts-node your-migration-script.ts` (assuming ts-node is installed)