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;
}