db-migrate
db-migrate is a robust database migration framework for Node.js, designed to manage schema changes across various SQL database systems. Its current stable version is 0.11.14, released in late 2019, with a `v1.0.0-beta.0` also from 2019. The project is currently in a maintenance phase, with ongoing commits to the GitHub repository but no new stable releases for several years. It supports a wide array of databases including PostgreSQL, MySQL, SQLite, and MSSQL, requiring separate driver packages for each. A key differentiator is its dual interface: a powerful command-line tool for everyday use and a comprehensive programmatic API for deeper integration into application deployment and testing workflows. It ensures transactional integrity for migrations and offers clear 'up' and 'down' scripts for reliable schema evolution and rollback capabilities.
Common errors
-
Error: Cannot find module 'db-migrate-<driver>'
cause The required database driver package (e.g., 'db-migrate-pg' for PostgreSQL) is not installed or incorrectly named.fixInstall the missing driver: `npm install db-migrate-<driver>` (e.g., `npm install db-migrate-pg`). Ensure the driver name in `database.json` matches the installed package suffix. -
Error: No database config found!
cause db-migrate could not find a `database.json` file in the current working directory or the directory specified by the `cwd` option.fixCreate a `database.json` file in your project root or ensure the `cwd` option for `DBMigrate.getInstance()` points to the correct directory where `database.json` resides. -
Error: db-migrate connection error. Please check your database credentials or connection string.
cause db-migrate failed to establish a connection to the database. This is typically due to incorrect credentials, host, port, database name in `database.json`, or the database server not running/being inaccessible.fixVerify all connection details in your `database.json` for the selected environment. Ensure the database server is running and accessible from the machine running db-migrate. -
TypeError: db.createTable is not a function (or similar for other DBMigrate API methods)
cause This error usually indicates an issue with how the migration file `exports.up` or `exports.down` is structured, specifically if the `db` object passed to these functions is not being correctly used.fixEnsure your migration files correctly define `exports.setup = function(options) { dbm = options.dbmigrate; ... };` and that `exports.up = function(db) { ... };` and `exports.down = function(db) { ... };` use the `db` object passed to them, which contains the API methods like `createTable`, `addColumn`, etc.
Warnings
- gotcha db-migrate is primarily a CommonJS module. While it can be used in ESM projects, direct `import DBMigrate from 'db-migrate'` might require build tool configuration or dynamic `import()` for seamless integration in a pure ESM environment.
- gotcha Each database type (PostgreSQL, MySQL, SQLite, MSSQL) requires its own `db-migrate-*` driver package (e.g., `db-migrate-pg`, `db-migrate-mysql`). Forgetting to install the correct driver for your configured database will lead to runtime errors.
- gotcha Configuration for db-migrate is typically done via a `database.json` file. Ensure this file is correctly located in your project's root or specified via the `cwd` option when using the programmatic API, otherwise, db-migrate might fail to initialize or connect to the database.
- deprecated The `v1.0.0-beta.0` release from 2019 was a beta and the project has not released a stable v1.0.0 since. While active, the core functionality resides in the 0.11.x branch, and future breaking changes are possible if a stable v1 is ever released.
Install
-
npm install db-migrate -
yarn add db-migrate -
pnpm add db-migrate
Imports
- DBMigrate
import DBMigrate from 'db-migrate';
const DBMigrate = require('db-migrate'); - getInstance (default)
const dbmigrate = new DBMigrate();
const dbmigrate = DBMigrate.getInstance(true);
- getInstance (custom options)
const dbmigrate = DBMigrate.getInstance({ cwd: __dirname });const dbmigrate = DBMigrate.getInstance(false, { cwd: __dirname, env: 'production' });
Quickstart
import DBMigrate from 'db-migrate';
import path from 'path';
import fs from 'fs';
async function runExampleMigrations() {
const migrationsDirPath = path.join(__dirname, 'migrations');
// Ensure migrations directory exists for db-migrate to scan
if (!fs.existsSync(migrationsDirPath)) {
fs.mkdirSync(migrationsDirPath);
}
// Create a simple migration file (up and down)
const migrationName = `create-test-table-${Date.now()}`;
const migrationFilePath = path.join(migrationsDirPath, `${migrationName}.js`);
const migrationContent = `
'use strict';
var dbm;
var type;
var seed;
exports.setup = function(options) {
dbm = options.dbmigrate;
type = options.type;
seed = options.seed;
};
exports.up = function(db) {
console.log('Running UP migration: ${migrationName}');
return db.createTable('test_table', {
id: { type: 'int', primaryKey: true, autoIncrement: true },
value: { type: 'string', length: 255 }
});
};
exports.down = function(db) {
console.log('Running DOWN migration: ${migrationName}');
return db.dropTable('test_table');
};
exports._meta = {
"version": 1
};
`;
fs.writeFileSync(migrationFilePath, migrationContent);
console.log(`Generated migration file: ${migrationName}.js`);
// Create a minimal database.json for an in-memory SQLite database
const configPath = path.join(__dirname, 'database.json');
const dbConfig = {
"dev": {
"driver": "sqlite3",
"filename": ":memory:", // Use in-memory SQLite for easy testing
"host": "localhost", // Required by some db-migrate internals even for sqlite3
"database": "testdb" // Required by some db-migrate internals
}
};
fs.writeFileSync(configPath, JSON.stringify(dbConfig, null, 2));
console.log('Generated database.json for in-memory SQLite.');
let dbmigrate;
try {
// Initialize db-migrate with options
dbmigrate = DBMigrate.getInstance(true, {
cwd: __dirname, // Important for db-migrate to find config and migrations
env: 'dev'
});
console.log('\n--- Running UP migrations ---');
await dbmigrate.up();
console.log('UP migrations complete.');
console.log('\n--- Running DOWN migrations ---');
await dbmigrate.down();
console.log('DOWN migrations complete.');
} catch (error) {
console.error('Migration failed:', error);
process.exit(1);
} finally {
// Cleanup generated files
if (fs.existsSync(migrationFilePath)) {
fs.unlinkSync(migrationFilePath);
}
if (fs.existsSync(configPath)) {
fs.unlinkSync(configPath);
}
if (fs.existsSync(migrationsDirPath)) {
fs.rmdirSync(migrationsDirPath, { recursive: true });
}
}
}
runExampleMigrations();