sequelize-dry-run
v1.0.1
Published
A tool to preview Sequelize migrations SQL queries without executing them
Maintainers
Readme
sequelize-dry-run
A lightweight npm package to preview Sequelize migration SQL queries without executing them on your database. Perfect for reviewing changes before applying them in production.
Features
- 🔍 Preview SQL queries generated by Sequelize migrations
- ⚡ Zero database modifications - completely safe dry-run mode
- 📦 Simple programmatic API
- 🎯 Works with existing Sequelize and Umzug setup
- 🔄 Supports both up (migrate) and down (rollback) operations
Installation
npm install sequelize-dry-runPeer Dependencies: This package requires sequelize (>=6.0.0) and umzug (>=3.0.0) to be installed in your project.
npm install sequelize umzugUsage
Basic Example
const { Sequelize } = require('sequelize');
const { createDryRun } = require('sequelize-dry-run');
// Initialize your Sequelize instance
const sequelize = new Sequelize({
dialect: 'mysql',
host: 'localhost',
database: 'mydb',
username: 'root',
password: 'password',
});
// Create dry-run executor
const dryRun = createDryRun({
sequelize,
migrationsPath: './db/migrations',
verbose: true, // Show output in console
});
// Preview pending migrations
(async () => {
const results = await dryRun.up();
results.forEach(result => {
console.log(`Migration: ${result.name}`);
console.log('SQL Queries:', result.sql);
});
})();Rollback (Down) Migrations
const result = await dryRun.down();
if (result) {
console.log(`Would rollback: ${result.name}`);
console.log('SQL Queries:', result.sql);
} else {
console.log('No migrations to rollback');
}Using Callbacks
const dryRun = createDryRun({
sequelize,
migrationsPath: './db/migrations',
verbose: false,
});
await dryRun.up({
onMigration: (name, queries) => {
console.log(`Processing: ${name}`);
queries.forEach(sql => console.log(` - ${sql}`));
}
});Using Your Own Logger
You can pass your own logger instance (e.g., Winston, Pino, Bunyan) instead of using console:
const winston = require('winston');
const customLogger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'migrations.log' })
]
});
const dryRun = createDryRun({
sequelize,
migrationsPath: './db/migrations',
verbose: true,
logger: customLogger, // Use your own logger
});
await dryRun.up();Or with a simple custom logger:
const myLogger = {
log: (msg) => {
// Your custom logging logic
console.log(`[DRY-RUN] ${msg}`);
}
};
const dryRun = createDryRun({
sequelize,
migrationsPath: './db/migrations',
verbose: true,
logger: myLogger,
});CLI Script Example
Create a script in your project (e.g., scripts/migrate-dry-run.js):
#!/usr/bin/env node
const { createDryRun } = require('sequelize-dry-run');
const db = require('./db'); // Your sequelize instance
const direction = process.argv.includes('--down') ? 'down' : 'up';
(async () => {
const dryRun = createDryRun({
sequelize: db.sequelize,
migrationsPath: './db/migrations',
verbose: true,
});
if (direction === 'up') {
await dryRun.up();
} else {
await dryRun.down();
}
})();Then add to your package.json:
{
"scripts": {
"migrate:dry": "node scripts/migrate-dry-run.js",
"migrate:dry:down": "node scripts/migrate-dry-run.js --down"
}
}API Reference
createDryRun(options)
Creates a dry-run migration executor.
Parameters:
options(Object)sequelize(Object, required): Sequelize instancemigrationsPath(String, required): Path to migrations folder (absolute or relative to cwd)tableName(String, optional): Name of the migrations table. Default:'SequelizeMeta'verbose(Boolean, optional): Enable console output. Default:falselogger(Object, optional): Custom logger instance withlog()method. Default:console
Returns: Object with up and down methods
dryRun.up([options])
Preview pending migrations.
Parameters:
options(Object, optional)onMigration(Function): Callback called for each migration with(name, sql)parameters
Returns: Promise - Array of migration results
Result object:
{
name: 'migration-name.js',
direction: 'up',
sql: ['SQL query 1', 'SQL query 2', ...],
output: 'formatted string output'
}dryRun.down([options])
Preview rolling back the last migration.
Parameters:
options(Object, optional)onMigration(Function): Callback called with(name, sql)parameters
Returns: Promise<Object|null> - Migration result or null if no migrations to rollback
How It Works
The package temporarily patches Sequelize's query execution and Umzug's storage methods to:
- Capture all SQL queries generated by migrations
- Prevent actual database writes
- Bypass SequelizeMeta table updates
All patches are automatically restored after execution, leaving your Sequelize instance in its original state.
Use Cases
- 📝 Review migration SQL before production deployment
- 🔍 Debug complex migration logic
- 📊 Generate migration documentation
- 🧪 Test migrations in CI/CD pipelines
- 🎓 Learn how Sequelize generates SQL
Limitations
- Only works with JavaScript migration files (not TypeScript directly)
- Requires migrations to be compatible with Umzug 3.x
- SELECT queries for metadata are still executed (but not data modifications)
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
License
MIT
