跳至主要内容

[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

相關文章

Reference