Hướng dẫn sử dụng migration và seeder trong sequelize

12:09 14/02/2025

Sequelize hỗ trợ dùng migration để tạo, chỉnh xóa , cấu trúc các table trong database, tạo quan hệ giữa các database… Công cụ này rất hữu ích khi database trong dự án là khá phức tạp, và bạn làm việc trong team có nhiều người. 

Mỗi 1 file migration được tạo ra để tạo 1 table nào đó, trong mỗi file này có hai hàm up và down, các hàm này sẽ thực thi khi bạn chạy migrgation hoặc undo migration.

Cài đặt sequelize-cli

Để tạo mirgration, bạn cần cài đặt sequelize và cài thêm gói sequelize-cli vào dự án theo lệnh như sau:   npm install  sequelize  sequelize-cli

Sau đó muốn làm việc với hệ quản trị datable nào thì cài thêm driver của hệ quản trị đó: 

npm install pg pg-hstore  # Postgres
npm install mysql2    # mysql
npm install sqlite3   # sqlite
npm install tedious   # Microsoft SQL Server
npm install oracledb  # Oracle Database

Khởi tạo dự án

Tạo 1 folder project trống và chạy lệnh sau để khởi tạo npx sequelize-cli init. Lệnh chạy xong sẽ tạo các folder như sau :

  • folder config chứa các file cấu hình (như thông số kết nối database) để sequelize-cli hoạt động
  • folder models chứa các model tương tác các table trong project
  • folder migrations chứa các file migration để tạo , sử, xóa các table
  • folder seeders chứa các file dùng để chèn data vào các table 

Cấu hình

Cấu hình kết nối database là cấu hình quan trọng nhất, bạn khai báo trong file config.json trong folder config. Cách khai báo như sau: 

{
  “development”: {
    “username”: “root”,
    “password”: null,
    “database”: “database_development”,
    “host”: “127.0.0.1”,
    “dialect”: “mysql”
  },
  “test”: {
    “username”: “root”,
    “password”: null,
    “database”: “database_test”,
    “host”: “127.0.0.1”,
    “dialect”: “mysql”
  },
  “production”: {
    “username”: “root”,
    “password”: null,
    “database”: “database_production”,
    “host”: “127.0.0.1”,
    “dialect”: “mysql”
  }
}

Thực tập dùng mirgration tạo table với sequelize

Phần trên chỉ là giới thiệu, còn bây giờ, chúng ta sẽ thực thành trực tiếp nhé:

Tạo project và cài các module

  1. Tạo foder project trống (ví dụ test2) rồi chuyển vào folder mới tạo

2. Cài gói sequelize và  sequelize-cli: Trong folder project chạy lệnh sau để cài 2 gói

npm install sequelize  sequelize-cli

  1. Cài thêm module mysql2 để sequelize tương tác với mysql: npm install mysql2

  1. Khởi tạo cấu hình 

Trong folder project chạy lệnh sau để tạo các cấu hình cần cho sequelize hoạt động: npx sequelize-cli  init

Lệnh trên sẽ tạo các file và folder như trong hình sau:

 5. Cấu hình database

  • Tạo 1 database tên gì đó (ví dụ test2) để thực tập

  • Mở file config/config.json và cấu hình tên database, và username password cho đúng. 

Tạo các migration

Trong folder project, chạy các lệnh sau để tạo migration cho 3 bảng loại, san pham và users:

npx sequelize-cli model:generate  –name loai   –attributes  ten_loai:string
npx sequelize-cli model:generate   —name san_pham   —attributes ten_sp:string
npx sequelize-cli model:generate   —name user  —attributes email:string

Trong đó trong –name là tên , và các field khai báo trong –attributes, tạm thời chỉ khai báo 1 field trong table không cần khai báo hết, chút nữa bổ sung thêm.

Mỗi lệnh như trên sẽ tạo ra 1 file trong folder migrations và 1 file trong folder models, tên mỗi file migration bắt đầu bằng thời điểm tạo ra file, và đây chính là các file chúng ta dùng

Khai báo cấu trúc các bảng

Mở 1 file migration, bạn sẽ thấy trong đây có 2 hàm, hàm up để tạo table, hàm down để xóa table. Tên table bạn cần khai báo đúng trong 2 hàm này (trong lệnh createTable và dropTable) 

Trong hàm createTable, khai báo các field cho table, trong đó đã có sẵn 4 field là id (khóa chính), field createAt , updateAt, và field đã khai báo lúc tạo migration ở bước trên… Mỗi field có kiểu dữ liệu và nhiều thuộc tính. Bạn thay đổi, bổ sung các thuộc tính tùy nhu cầu (unique là duy nhất, primaryKey là khóa chính, defaultValue là giá trị mặc định, allowNull: cho phép null…)

Ngoài 4 field đã có, bạn khai báo thêm các field khác để có được các field đầy đủ của table. 

Gợi ý khai báo bảng loai như sau: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable(‘loai’, {
      id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER},
      ten_loai: { type: Sequelize.STRING, unique:true},
      thu_tu: { type: Sequelize.INTEGER, defaultValue:0 },
      an_hien: { type: Sequelize.BOOLEAN, defaultValue:0 },
      createdAt: { type: Sequelize.DATE, defaultValue:Sequelize.literal(‘CURRENT_TIMESTAMP’)},
      updatedAt: { type: Sequelize.DATE , defaultValue:Sequelize.literal(‘CURRENT_TIMESTAMP’)}
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable(‘loai’);
  }
};

Gợi ý khai báo cấu trúc bảng san_pham như sau: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable(‘san_pham’, {
      id: { autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER},
      ten_sp: { type: Sequelize.STRING(100), allowNull:false  },
      id_loai: { type: Sequelize.INTEGER, allowNull:false,
        references: {model: “loai”, key: “id”, comment:“khóa ngoại,ref đến field loai.id”}
      },
      gia: { type: Sequelize.INTEGER, defaultValue:0 , comment:“Giá gốc” },
     gia_km: { type: Sequelize.INTEGER, defaultValue:0, comment:“Giá khuyến mãi” },
      hinh: { type: Sequelize.STRING, allowNull:true, comment:“Hình chính của sp” },
      ngay: {allowNull: false, type: Sequelize.DATE, comment:“Ngày đăng”},
      luot_xem: { type: Sequelize.INTEGER, defaultValue:0, comment:“Số lần xem” },
      hot: { type: Sequelize.INTEGER, defaultValue:0 , comment:”0: bình thường, 1: nổi bật”},
      an_hien: {type: Sequelize.BOOLEAN, defaultValue:0 , comment:“0 là ẩn, 1 là hiện”},
      tinh_chat: {type: Sequelize.INTEGER, defaultValue:0 },
      createdAt: {type: Sequelize.DATE, defaultValue:Sequelize.literal(‘CURRENT_TIMESTAMP’)},
      updatedAt: {type: Sequelize.DATE, defaultValue:Sequelize.literal(‘CURRENT_TIMESTAMP’)}
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable(‘san_pham’);
  }
};

Gợi ý khai báo cấu trúc bảng users như sau: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable(‘users’, {
      id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER },
      email: {type: Sequelize.STRING, allowNull:false, unique: true },
      ho_ten: {type:Sequelize.STRING, allowNull:false, },
      mat_khau: {type:Sequelize.STRING, allowNull:false, },
     vai_tro: {type:Sequelize.BOOLEAN, defaultValue:0, comment:“0 là reqgister, 1 là admin” },
     createdAt: {allowNull: false, type: Sequelize.DATE },
      updatedAt: { allowNull: false, type: Sequelize.DATE }
    });
  },
  async down(queryInterface, Sequelize) {
    await queryInterface.dropTable(‘users’);
  }
};

Chạy migration

Trong folder project, chạy lệnh npx sequelize-cli db:migrate  

3 file mirgation đã tạo sẽ chạy và tạo thành 3 table trong database. Table users được tạo như sau, các thuộc tính của từng field được tạo đúng như khai báo

Table loai được tạo như sau: 

Table san_pham cũng được tạo như khai báo. 

Riêng field id_loai được tạo index và thiết lập quan hệ với field id của bảng loại. Nhắp tên database rồi chọn Designer bạn sẽ thấy quan hệ được thiết lập giữa bảng loaisan_pham luôn. 

Undo migration

Khi chạy lệnh npx sequelize-cli db:migrate thì các table sẽ được tạo ra. Thế khi muốn bỏ qua chức năng tạo table thì sao? Bạn chỉ việc chạy lệnh 

  • npx sequelize-cli db:migrate:undo => bỏ qua kết quả của migration cuối
  • npx sequelize-cli db:migrate:undo:all  => bỏ qua kết quả của tất cả các migration

Thực tập dùng seeder để chèn dữ liệu vào table 

Seed trong sequelize là gì

Seed trong sequelize giúp chèn nhiều dữ liệu vào trong các table một cách nhanh chóng mà không thực hiện thủ công mất thời gian qua giao diện của các tool quản trị như phpMyAdmin, Workbench. Việc dùng seeder để chèn data vào các table là rất cần thiết khi dự án bắt đầu vào giai đoạn code. Vì cần phải có dữ liệu để show ra trang web, để test các chức năng quản trị. Dữ liệu này có thể được xóa sửa và thêm lại nhiều lần trong quá trình phát triển của dự án. 

Tạo file seeder

Các file seeder sẽ được tạo bằng lệnh npx sequelize-cli seed:generate . Mời xem ví dụ sau là 3 lệnh tạo seeder để chèn vào các table loai, san_pham, users

  • npx sequelize-cli seed:generate –name chen_loai
  • npx sequelize-cli seed:generate –name chen_san_pham
  • npx sequelize-cli seed:generate –name chen_user 

Mỗi lệnh trên khi chạy sẽ tạo 1 file seed có 2 hàm up và down, trong hàm này bạn code để chèn , xóa dữ liệu trong các table

Code file seed chèn dữ liệu users

  • Cài module bscyptjs bằng lệnh: npm install bcryptjs   
  • Mở file xxx- chen_user.js và xóa hết code lại: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
const bc = require(“bcryptjs”);
module.exports = {
  async up (queryInterface, Sequelize) {
      const user_arr = [
        { ht:“Đỗ Đạt Cao”, email:[email protected],pass:“hehe”, vai_tro:1} ,
        { ht:“Đào Kho Báu”, email:[email protected],pass:“hehe”, vai_tro:0} ,
        { ht:“Đào Được Vàng”, email:[email protected],pass:“hehe”, vai_tro:0} ,
      ];
      for (let i=0; i< user_arr.length; i++) {
          let  row = user_arr[i];
          await queryInterface.bulkInsert(‘users’, [{
            email: row.ht,
            mat_khau: await bc.hash(row.pass, bc.genSaltSync(8)),
            vai_tro:row.vai_tro
          }], {} );
    }//for
  },
  async down (queryInterface, Sequelize) {
      await queryInterface.bulkDelete(‘users’, null, {});
  }
};

Code file seed chèn dữ liệu loại

Mở file xxx- chen_loai.js và xóa hết code lại: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
module.exports = {
  async up (queryInterface, Sequelize) {
    const loai_arr = [
      { id:1, ten:“Asus”} ,
      { id:2, ten:“Acer”} ,
      { id:3, ten:“Lenovo”} ,
      { id:4, ten:”MSI”} ,
      { id:5, ten:“HP”} ,
      { id:6, ten:”Dell”} ,
{ id:7, ten:”Apple”} ,
      { id:8, ten:“Surface”} ,
      { id:9, ten:“Masstel”} ,
      { id:10, ten:“LG”} ,
      { id:11, ten:“CHUWI”} ,
      { id:12, ten:“itel”} ,
    ];
    for (let i=0; i< loai_arr.length; i++) {
      let  row = loai_arr[i];
      await queryInterface.bulkInsert(‘loai’, [{
       id: row.id,
        ten_loai: row.ten,
        thu_tu: row.id,
        an_hien:1
      }], {});
    }//for
  },
  async down (queryInterface, Sequelize) {
     await queryInterface.bulkDelete(‘loai’, null, {});
  }
};

Code file seed chèn dữ liệu loại

Mở file xxx- chen_san_pham.js và xóa hết code lại: 

‘use strict’;
/** @type {import(‘sequelize-cli’).Migration} */
module.exports = {
  async up (queryInterface, Sequelize) {
    const loai_arr = [
      { id:1, ten:“Asus”} , { id:2, ten:“Acer”} , { id:3, ten:“Lenovo”} ,
      { id:4, ten:“MSI”} ,  { id:5, ten:“HP”} ,   { id:6, ten:“Dell”} ,
      { id:7, ten:“Apple”} ,{ id:8, ten:“Surface”} , { id:9, ten:“Masstel”} ,
      { id:10, ten:“LG”} ,  { id:11, ten:“CHUWI”} ,  { id:12, ten:“itel”} ,
    ];
    const lt1_arr = [‘Gaming ROG Strix’,‘Nitro 5 Gaming’,‘Ideapad Gaming 3’];
    const lt2_arr = [‘G15 G513IH’,’AN515 45 R6EV’,’15IHU6′,’11SC’,’Gaming VICTUS’];
const hinh_arr =[
      ‘asus-rog-strix-gaming-g513ih-r7-hn015w-2-1.jpg’,
      ‘vi-vn-acer-nitro-5-gaming-an515-45-r6ev-r5-nhqbmsv006-4.jpg’,
      ‘hp-pavilion-15-eg2062tx-i5-7c0w7pa-13.jpg’,
      ‘victus-15-fa0111tx-i5-7c0r4pa-glr-1.jpg’,
      ‘asus-zenbook-14-oled-ux3402va-i5-km085w–(6).jpg’,
      ‘macbook-pro-13-inch-m2-2022-231122-041529.jpg’,
      ‘masstel-e140-n4120-glr-2.jpg’
    ];
    for (let i=1; i<=200; i++){
      let gia = Math.floor(5000000 + Math.random()*(300000005000000 + 1))
      let giam = Math.floor(1000000 + Math.random()*(50000001000000 + 1));
      let gia_km = gia – giam;
      const loai = loai_arr[ Math.floor(Math.random() * loai_arr.length) ];
      let id_loai = loai.id;
      let ten_loai = loai.ten;
      let lt1_random = lt1_arr[ Math.floor(Math.random() * lt1_arr.length) ]       let lt2_random = lt2_arr[ Math.floor(Math.random() * lt2_arr.length) ]       let ten_sp = `${ten_loai} ${lt1_random} ${lt2_random}`
      let hinh = hinh_arr[ Math.floor(Math.random() * hinh_arr.length) ]       let nam = Math.floor(2024 + Math.random()*(20262024 + 1))
      let thang = Math.floor(1 + Math.random()*(121 + 1))
      let ngay = Math.floor(1 + Math.random()*(281 + 1))
      let gio = Math.floor(1 + Math.random()*(231 + 1))
      let phut = Math.floor(1 + Math.random()*(601 + 1))
      let giay = Math.floor(1 + Math.random()*(601 + 1))
      let randtime = `${nam}${thang}${ngay} ${gio}:${phut}:${giay}`;
      const hot_arr = [0,1,2,3,4,5,6,7,8,9,10]       let hot = hot_arr[ Math.floor(Math.random() * hot_arr.length) ] % 3 ==0 ? 1:0;
      const an_hien_arr = [0,1,5,35,3,67,49,5,61,7,19,9,10]       let an_hien = an_hien_arr[ Math.floor(Math.random() * an_hien_arr.length) ] % 3 ==0? 1:0;
      let luot_xem = Math.floor(0 + Math.random()*(10000 + 1))
      let tinh_chat = 1 ;// 1 bình thường, 2 giá rẻ, 3 giảm sốc, 4 cao cấp
      if (gia>=28000000) tinh_chat = 4;  //cao cấp
      else if (gia – gia_km >=3000000) tinh_chat = 3; //giảm sốc
      else if (gia <= 6000000) tinh_chat = 2;//giá rẻ
      else tinh_chat = 1;  //Bình thường
      let [id_sp, kq ] = await queryInterface.insert(null, ‘san_pham’, {
        ten_sp: ten_sp,   gia: gia,  gia_km:gia_km,  hinh: hinh ,
        id_loai: id_loai, hot:  hot, ngay: randtime ,
        luot_xem:  luot_xem, tinh_chat:tinh_chat, an_hien: an_hien,
      }, {} );
    }//for
  },
  async down (queryInterface, Sequelize) {
     await queryInterface.bulkDelete(‘san_pham’, null, {});
  }
};

Chạy các file seed

npx sequelize-cli db:seed:all

Kết quả chạy trong database sẽ có dữ liệu

Undo seed

npx sequelize-cli db:seed:undo:all
asd

Giảng viên Nguyễn Văn Long
Bộ môn Công nghệ thông tin
FPT Polytechnic TP HCM

Cùng chuyên mục

Đăng Kí học Fpoly 2025

  • Max. file size: 50 MB.
  • Max. file size: 50 MB.
  • Max. file size: 50 MB.