Database migration framework for Node.js applications that enables developers to programmatically manage database schema changes and evolution over time.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Data seeding functionality for populating databases with initial or test data. db-migrate supports both version-controlled and static seeding approaches, allowing you to manage data insertion and removal with the same precision as schema migrations.
Execute database seeding operations to populate tables with data.
/**
* Execute database seeding operations
* @param mode - Seeding mode: 'vc' (version controlled) or 'static'
* @param scope - Seeding scope/mode (string) or callback (function)
* @param callback - Completion callback (function)
* @returns Promise
*/
seed(mode, scope, callback): Promise;Usage Examples:
const dbMigrate = require('db-migrate');
const instance = dbMigrate.getInstance();
// Run version-controlled seeds (default)
await instance.seed();
// Explicitly run version-controlled seeds
await instance.seed('vc');
// Run static seeds
await instance.seed('static');
// With callback
instance.seed('vc', (err) => {
if (err) console.error('Seeding failed:', err);
else console.log('Seeding completed');
});
// With scope
await instance.seed('vc', 'user-data');Undo seed operations by running the down methods of previously executed seeds.
/**
* Undo seed operations (rollback seeding)
* @param specification - Count (number) or callback (function)
* @param scope - Seeding scope/mode (string)
* @param callback - Completion callback (function)
* @returns Promise
*/
undoSeed(specification, scope, callback): Promise;Usage Examples:
// Undo the last seed
await instance.undoSeed(1);
// Undo the last 3 seeds
await instance.undoSeed(3);
// With callback
instance.undoSeed(2, (err) => {
if (err) console.error('Undo seed failed:', err);
else console.log('Seeds undone');
});
// With scope
await instance.undoSeed(1, 'user-data');Reset all seeds by undoing all previously executed seed operations.
/**
* Reset all seeds by undoing all executed seeds
* @param specification - Count parameter (ignored for API consistency with undoSeed)
* @param scope - Seeding scope/mode (string) or callback (function)
* @param callback - Completion callback (function)
* @returns Promise
*/
resetSeed(specification?, scope, callback): Promise;Note: The specification parameter is ignored internally - resetSeed always resets all seeds regardless of the count provided. This parameter exists for API consistency with undoSeed.
Usage Examples:
// Reset all seeds
await instance.resetSeed();
// With callback
instance.resetSeed(null, (err) => {
if (err) console.error('Reset seed failed:', err);
else console.log('All seeds reset');
});
// With scope
await instance.resetSeed(null, 'user-data');Version-controlled seeds work like migrations - they track which seeds have been applied and can be rolled back.
Directory Structure:
seeds/
├── vc/
│ ├── 20231201120000-add-default-users.js
│ ├── 20231201130000-add-sample-products.js
│ └── 20231201140000-add-test-data.js
└── static/
├── users.json
└── products.jsonVersion Controlled Seed File:
'use strict';
var dbm;
var type;
var seed;
exports.setup = function(options, seedLink) {
dbm = options.dbmigrate;
type = dbm.dataType;
seed = seedLink;
};
exports.up = function(db) {
return db.insert('users', [
{ name: 'Admin User', email: 'admin@example.com', role: 'admin' },
{ name: 'Test User', email: 'test@example.com', role: 'user' }
]);
};
exports.down = function(db) {
return db.runSql("DELETE FROM users WHERE email IN ('admin@example.com', 'test@example.com')");
};
exports._meta = {
"version": 1
};Static seeds are simple data files that are loaded each time seeding runs, without version tracking.
Static Seed File (JSON):
{
"users": [
{ "name": "Default Admin", "email": "admin@site.com", "role": "admin" },
{ "name": "Demo User", "email": "demo@site.com", "role": "user" }
],
"categories": [
{ "name": "Electronics", "slug": "electronics" },
{ "name": "Books", "slug": "books" }
]
}Seeding operations are available through the command-line interface:
# Run version-controlled seeds
db-migrate seed
# Run static seeds
db-migrate seed:static
# Undo seeds
db-migrate seed:down
# Reset all seeds
db-migrate seed:reset
# With environment
db-migrate seed --env test
# With specific count
db-migrate seed:down -c 2Create seed files manually or using templates:
Manual Creation:
// seeds/vc/20231201120000-add-sample-users.js
'use strict';
exports.setup = function(options, seedLink) {
// Setup code
};
exports.up = function(db) {
return db.insert('users', [
{ name: 'Alice Smith', email: 'alice@example.com' },
{ name: 'Bob Jones', email: 'bob@example.com' }
]);
};
exports.down = function(db) {
return db.runSql("DELETE FROM users WHERE email IN ('alice@example.com', 'bob@example.com')");
};
exports._meta = {
"version": 1
};Seeds have access to database interface methods for data manipulation:
exports.up = function(db) {
// Insert single record
return db.insert('users', {
name: 'John Doe',
email: 'john@example.com'
});
// Insert multiple records
return db.insert('users', [
{ name: 'Alice', email: 'alice@example.com' },
{ name: 'Bob', email: 'bob@example.com' }
]);
};exports.up = function(db) {
return db.runSql(`
INSERT INTO users (name, email, created_at)
VALUES
('Admin', 'admin@site.com', NOW()),
('User', 'user@site.com', NOW())
`);
};
exports.down = function(db) {
return db.runSql("DELETE FROM users WHERE email IN ('admin@site.com', 'user@site.com')");
};exports.up = function(db) {
return db.runSql("UPDATE users SET status = 'active' WHERE role = 'admin'");
};exports.up = function(db) {
// Link to another seed
seed.link('20231201130000-add-categories');
return db.insert('products', [
{ name: 'Laptop', category_id: 1 },
{ name: 'Book', category_id: 2 }
]);
};Seeding respects the same configuration as migrations:
{
"development": {
"driver": "mysql",
"host": "localhost",
"user": "root",
"password": "password",
"database": "myapp_development",
"seeds-table": "seeds_meta",
"vcseeder-dir": "seeds/vc",
"staticseeder-dir": "seeds/static"
}
}// Development seeds
const devInstance = dbMigrate.getInstance(true, { env: 'development' });
await devInstance.seed('vc');
// Test seeds
const testInstance = dbMigrate.getInstance(true, { env: 'test' });
await testInstance.seed('static');
// Production seeds (usually minimal)
const prodInstance = dbMigrate.getInstance(true, { env: 'production' });
await prodInstance.seed('vc'); // Only essential datatry {
await instance.seed('vc');
} catch (error) {
if (error.message.includes('duplicate key')) {
console.log('Seed data already exists, skipping...');
} else if (error.message.includes('foreign key')) {
console.error('Seed references missing data, check dependencies');
throw error;
} else {
throw error;
}
}async function setupDevelopmentData() {
const instance = dbMigrate.getInstance(true, { env: 'development' });
// Run migrations first
await instance.up();
// Then seed data
await instance.seed('vc');
console.log('Development environment ready with sample data');
}async function setupTestData() {
const instance = dbMigrate.getInstance(true, { env: 'test' });
// Reset seeds for clean test state
await instance.resetSeed();
// Apply fresh test data
await instance.seed('static');
}/**
* Seeding mode specification
*/
type SeedMode = 'vc' | 'static';
/**
* Seed specification for targeting specific counts
*/
type SeedSpecification = number | (() => void);
/**
* Seeding scope for organizing seeds
*/
type SeedScope = string;
/**
* Seed callback function signature
*/
type SeedCallback = (error?: Error, result?: any) => void;
/**
* Database interface available in seed files
*/
interface SeedDatabase {
/** Insert data into table */
insert(tableName: string, data: object | object[]): Promise<any>;
/** Update data in table */
update(tableName: string, data: object, where: object): Promise<any>;
/** Delete data from table */
delete(tableName: string, where: object): Promise<any>;
/** Truncate table (remove all data) */
truncate(tableName: string): Promise<any>;
/** Execute raw SQL query */
runSql(sql: string, params?: any[]): Promise<any>;
/** Lookup data from table */
lookup(spec: object): Promise<any>;
/** Build WHERE clause from specification object */
buildWhereClause(spec: object): string;
/** Escape string for SQL safety */
escapeString(str: string): string;
/** Escape value for SQL safety */
escape(str: any): string;
/** Quote array values for SQL */
quoteArr(arr: any[]): string;
}