node-pg-migrate
repository·main·Indexed 23 days ago
https://github.com/salsita/node-pg-migrateA PostgreSQL database migration management tool for node.js that allows defining and executing schema changes using JavaScript, TypeScript, or SQL. It provides both a CLI and a programmatic API via the runner() function to manage migrations, supporting features like transaction control, custom migration loader strategies, and flexible database connection configurations via environment variables or JSON files.
What's inside node-pg-migrate
- node-pg-migrate is a database migration management tool for Node.js built specifically for PostgreSQL. While optimized for Postgres, it can also be used with other databases that conform to the SQL standard, such as CockroachDB.
Overview of node-pg-migrate
mainnode-pg-migrate is a PostgreSQL database migration management tool. It provides CLI support for managing up-down migrations, ensuring smooth database transitions. It also offers TypeScript support and a programmatic API for advanced customization and automation, allowing for flexible schema manipulation via direct SQL generation.Understand migration locking
mainTo prevent multiple migration processes from running simultaneously,node-pg-migrateuses a PostgreSQL advisory lock. This lock is held for the duration of the database session. If a migration script hangs or freezes, you must manually kill the database session before you can run another migration.Run migrations without a transaction using `pgm.noTransaction`
mainBy default,
node-pg-migrateruns all operations within a single transaction. However, certain operations (likepgm.addTypeValue) may fail if the type was created in a previous migration and the current migration is wrapped in a new transaction.To handle these cases, wrap your migration logic in
pgm.noTransaction().Warning: Using
pgm.noTransactionmeans that if an error occurs during the migration, the changes made up to that point will not be rolled back, potentially leaving your database in a partially migrated state.Handle case sensitivity and identifier quoting
mainPostgreSQL treats unquoted identifiers as case-insensitive (folding them to lowercase), but quoted identifiers are case-sensitive.
Because
node-pg-migratealways quotes all identifiers, you must ensure that:- Your manual SQL queries also use quotes for identifiers.
- Or, you use only lowercase identifiers to avoid confusion.
Decamelize Flag: You can use the
decamelizeconfiguration flag to automatically convert camelCase identifiers to snake_case (lowercase) using thedecamelizepackage.Handle automatic and manual down migrations
mainIf you do not provide an
export const downfunction,node-pg-migratewill attempt to automatically infer the rollback operations by reversing theupoperations.Note that not all operations can be automatically reversed. If a migration is destructive and cannot be rolled back, set
export const down = falseto prevent the tool from attempting an impossible rollback.Define column options in migrations
mainWhen using
createTableoraddColumns, you can define columns using a key/value object. Each key is the column name, and the value is an object containing configuration options.Commonly used options include:
type: The PostgreSQL data type (e.g.,'text','integer').array: Set totrueforARRAYor a number forARRAY[n].unique: Boolean to add a unique constraint.primaryKey: Boolean to make the column the primary key.notNull: Boolean to setNOT NULL.default: A string for theDEFAULTclause (can be a literal,null, or apgm.func()expression).references: The table name for a foreign key.onDelete/onUpdate: Constraints for foreign key actions.comment: A string to add a comment to the column.
Create and run your first migration
mainFollow these steps to apply a new schema change to your database:
- Create the migration file: Run
npm run migrate create <name>. This generates a new file in themigrations/directory. - Define the migration: Edit the generated file to include
up(to apply changes) anddown(to revert changes) functions. Theupfunction receives apgm(orMigrationBuilderin TS) object to perform schema operations. - Apply the migration: Set your
DATABASE_URLenvironment variable and runnpm run migrate up.
Example command:
DATABASE_URL=postgres://user:pass@localhost:5432/db npm run migrate up- Create the migration file: Run
Install node-pg-migrate
mainTo use
node-pg-migrate, you must first ensure you have thepglibrary installed as a dependency. Then, installnode-pg-migrateas a development dependency.Note that installing this module adds a runnable file to your
node_modules/.bindirectory. If installed locally, you can run it via./node_modules/.bin/node-pg-migrate.jsor by adding it to yourpackage.jsonscripts.npm add pg npm add --save-dev node-pg-migrateConfigure a migration script for TypeScript in package.json
mainTo simplify running TypeScript migrations, add a
migratescript to yourpackage.jsonusing the-j tsflag. This allows you to execute migrations using your preferred package manager.{ "scripts": { "migrate": "node-pg-migrate -j ts" } }Preconditions for node-pg-migrate
mainBefore using
node-pg-migrate, ensure your environment meets the following requirements:- Node.js: version 22 or higher.
- PostgreSQL: version 14 or higher (lower versions may work but are not officially supported).
- Dependencies: The
pglibrary must be installed in your project.
Update TypeScript/JS loading configuration for v9+
mainStarting with
v9,node-pg-migrateusesjitito handle TypeScript and mixed-extension migrations automatically. You no longer needts-node,tsx, or Babel.Removed CLI flags
--ts-node--tsx--tsconfig
Handling Path Aliases
If you used
--tsconfigto resolve path aliases intsconfig.json, you must now use the--tsconfig-pathsflag. You can passtrueto enable auto-discovery or provide a specific path to the config file.# Auto-discover tsconfig.json node-pg-migrate up -j ts --tsconfig-paths true # Use a specific tsconfig.json node-pg-migrate up -j ts --tsconfig-paths ./config/tsconfig.json// Update your package.json scripts from this: { "scripts": { "migrate": "ts-node node_modules/.bin/node-pg-migrate -j ts" } } // To this: { "scripts": { "migrate": "node-pg-migrate -j ts" } }