[Node.js] Sequelize Seeds
Seeds 是 Sequelize 用來管理測試資料和初始資料的機制。 透過 Seeders,可以快速建立開發或測試環境所需的資料,確保團隊成員擁有一致的資料狀態。
什麼是 Seeds ?
- Seeds 是用來填充資料庫初始資料或測試資料的檔案
- 與 Migration 不同,Seeds 主要處理「資料內容」而非「資料結構」
- 適合用於開發環境、測試環境的資料準備
使用場景
- 開發環境的測試資料
- 應用程式的初始資料(如預設管理員帳號、系統設定)
- Demo 展示用的範例資料
- 單元測試或整合測試的固定資料集
建立 Seeder
產生 Seeder 檔案
sequelize seed:generate --name demo-users
會在 seeders/ 目錄下產生檔案:<YYYYMMDDHHMMSS>-demo-users.js
執行 Seeders
# 執行所有 seeders
sequelize db:seed:all
# 執行特定 seeder
sequelize db:seed --seed <YYYYMMDDHHMMSS>-demo-users.js
復原 Seeders
# 復原最近一次的 seeder
sequelize db:seed:undo
# 復原特定 seeder
sequelize db:seed:undo --seed <YYYYMMDDHHMMSS>-demo-users.js
# 復原所有 seeders
sequelize db:seed:undo:all
Seeder 檔案結構
Seeder 檔案同樣包含 up() 和 down() 方法:
seeders/<TIMESTAMP>-demo-users.js
"use strict";
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.bulkInsert(
"Users",
[
{
name: "John Doe",
email: "john@example.com",
createdAt: new Date(),
updatedAt: new Date(),
},
{
name: "Jane Smith",
email: "jane@example.com",
createdAt: new Date(),
updatedAt: new Date(),
},
],
{},
);
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete("Users", null, {});
},
};
常用方法
bulkInsert(tableName, records, options)- 批次新增資料bulkDelete(tableName, where, options)- 批次刪除資料bulkUpdate(tableName, values, where, options)- 批次更新資料
實用範例
使用 Model 建立資料
const { User } = require("../models");
module.exports = {
up: async (queryInterface, Sequelize) => {
await User.bulkCreate([
{ name: "Admin", email: "admin@example.com", role: "admin" },
{ name: "User", email: "user@example.com", role: "user" },
]);
},
down: async (queryInterface, Sequelize) => {
await User.destroy({
where: { email: ["admin@example.com", "user@example.com"] },
});
},
};
條件式刪除
module.exports = {
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete(
"Users",
{
email: { [Sequelize.Op.like]: "%@example.com" },
},
{},
);
},
};
關聯資料的 Seed
module.exports = {
up: async (queryInterface, Sequelize) => {
// 先建立 Users
const users = await queryInterface.bulkInsert(
"Users",
[
{
name: "John",
email: "john@example.com",
createdAt: new Date(),
updatedAt: new Date(),
},
],
{ returning: true },
);
// 再建立關聯的 Posts
await queryInterface.bulkInsert(
"Posts",
[
{
title: "First Post",
content: "Hello World",
userId: users[0].id,
createdAt: new Date(),
updatedAt: new Date(),
},
],
{},
);
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete("Posts", null, {});
await queryInterface.bulkDelete("Users", null, {});
},
};
注意事項
Seeds 不會自動追蹤執行狀態
與 Migration 不同,Sequelize 預設不會追蹤哪些 Seeds 已經執行過。
這意味著執行 db:seed:all 可能會重複插入資料。
解決方案:
- 在 Seeder 中加入檢查邏輯,避免重複插入
- 使用
db:seed:undo:all清空後再重新執行 - 考慮使用 sequelize-cli-typescript 等擴充套件
生產環境使用建議
- Seeds 主要用於開發和測試環境
- 生產環境的初始資料建議透過 Migration 或專門的部署腳本處理
- 避免在生產環境執行
db:seed:undo:all,可能會清空重要資料
See Also
相關文章
- Sequelize Migration - 資料庫結構變更管理