การทำ Data Migration และ Seeder: คู่มือสำหรับ Developer

การทำ Data Migration และ Seeder: คู่มือสำหรับ Developer

ถ้าพูดถึงการพัฒนาแอปพลิเคชันที่เชื่อมต่อกับ Database หนึ่งในความยุ่งยากที่สุดคือการจัดการ Database structure ที่เปลี่ยนไปตามฟีเจอร์ใหม่ๆ ที่เพิ่มเข้ามา เช่น เพิ่มตาราง (Table) เปลี่ยนชนิดข้อมูล (Data type) หรือลบฟิลด์ (Field) ออกไป และแน่นอนว่า การเติมข้อมูลตัวอย่างหรือข้อมูลพื้นฐานก็ไม่ใช่เรื่องง่าย

ที่นี่เองที่ Data Migration และ Seeder จะมาช่วยให้ชีวิต Developer ง่ายขึ้น! 🎉


Data Migration คืออะไร?

Migration ก็คือกระบวนการ "เขียนโค้ด" เพื่อปรับเปลี่ยน Database structure โดยเฉพาะ ไม่ว่าจะเป็นการ db up (เพิ่มโครงสร้างใหม่) หรือ db down (ลบหรือย้อนโครงสร้างกลับ)

ตัวช่วยนี้ออกแบบมาเพื่อลดข้อผิดพลาดจากการแก้ไข Database structure ด้วยมือ (Manual) ซึ่งอาจทำให้เกิดปัญหาตามมา เช่น ลืมอัปเดตโครงสร้างบางส่วน หรือทีม Developer คนอื่นๆ ในทีมไม่รู้ว่ามีการเปลี่ยนแปลงอะไรบ้าง


Seeder คืออะไร?

Seeder ใช้สำหรับเติมข้อมูลใน Database โดยอัตโนมัติ เช่น ข้อมูล mock สำหรับการทดสอบ หรือข้อมูลพื้นฐานที่ระบบต้องใช้ เช่น ชื่อประเทศ, สิทธิ์ผู้ใช้งาน (Roles) หรือสินค้าในร้านค้า

ถ้าคุณเคยเสียเวลาเติมข้อมูลเดิมๆ เพื่อทดสอบระบบ Seeder จะช่วยประหยัดเวลาได้มาก และยังช่วยลดข้อผิดพลาดที่เกิดจากการพิมพ์ข้อมูลผิดได้ด้วย


Use Case ของ db up และ db down

เมื่อไหร่เราจะใช้ db up

  1. เพิ่มฟีเจอร์ใหม่
    เช่น คุณต้องการเพิ่มระบบเก็บคะแนน (Points system) สำหรับผู้ใช้งาน อาจต้องเพิ่มตารางใหม่ชื่อ points หรือเพิ่มคอลัมน์ total_points ในตาราง users
  2. ปรับปรุงระบบเดิมให้ดียิ่งขึ้น
    เช่น เปลี่ยนชนิดข้อมูลของคอลัมน์จาก STRING เป็น TEXT เพราะข้อมูลมีความยาวมากขึ้น
  3. สร้างฐานข้อมูลใหม่ในสภาพแวดล้อมอื่นๆ
    เช่น คุณต้องการสร้าง Database structure เดิมทั้งหมดในระบบ staging หรือ production

เมื่อไหร่เราจะใช้ db down

  1. Rollback การเปลี่ยนแปลงที่ผิดพลาด
    เช่น เพิ่มตารางผิด หรือคอลัมน์ใหม่ไม่จำเป็นแล้ว เราสามารถ db down เพื่อลบโครงสร้างนั้นออก
  2. ทดลองโค้ดในสภาพแวดล้อม Development
    เช่น คุณอาจต้องการลองเพิ่ม/ลบ Database structure หลายครั้งเพื่อทดสอบ

ในทางกลับกัน...เมื่อ Rollback Code แล้ว Database ล่ะ?

"อ้าว! แล้ว Database ล่ะ จะ Rollback ยังไง?"
นี่คือจุดที่ Migration มีบทบาทสำคัญ!

การใช้ Migration ทำให้เราสามารถ Rollback Database ได้ด้วยคำสั่ง db down ซึ่งจะย้อนการเปลี่ยนแปลงกลับไปยังสถานะก่อนหน้า เช่น ลบตารางที่สร้างใหม่ หรือคืนค่าโครงสร้างเดิมกลับมา


ข้อดี-ข้อเสียของ Data Migration และ Seeder

ข้อดีของ Data Migration

  • สะดวก: ไม่ต้องแก้ Database structure ด้วย SQL ทีละคำสั่ง
  • ลดความผิดพลาด: Migration Script ถูกทดสอบแล้ว และสามารถแชร์ให้ทีม Developer ใช้ได้
  • จัดการเวอร์ชันได้: สามารถ Rollback หรือย้อนกลับไปยังสถานะก่อนหน้าได้

ข้อเสียของ Data Migration

  • ซับซ้อนในโครงการใหญ่: Migration หลายไฟล์อาจทำให้การจัดการยุ่งยาก
  • ต้องระวังข้อมูลจริง (Production): การรัน Migration ที่ผิดพลาดอาจกระทบกับข้อมูลสำคัญ

ข้อดีของ Seeder

  • สะดวกสำหรับการทดสอบ: เติมข้อมูล mock ได้เร็ว
  • ลดข้อผิดพลาด: ไม่ต้องพิมพ์ข้อมูลด้วยมือ

ข้อเสียของ Seeder

  • ไม่เหมาะกับ Production: Seed Data อาจทับข้อมูลจริงในระบบ
  • ข้อมูลที่เยอะเกินไป: Seeder ที่เติมข้อมูลมากเกินไปอาจทำให้ Database หน่วง

ตัวอย่างการทำ db up / db down

สร้าง Migration สำหรับเพิ่มตาราง users

npx sequelize-cli migration:generate --name create-users-table

ไฟล์ที่สร้างขึ้น (ใน /migrations) จะมีโครงสร้างประมาณนี้:

module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      email: {
        type: Sequelize.STRING,
        unique: true,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface) => {
    await queryInterface.dropTable('Users');
  },
};

รัน db up

เพิ่มตารางใน Database:

npx sequelize-cli db:migrate

รัน db down

ลบตารางที่เพิ่งเพิ่มไป:

npx sequelize-cli db:migrate:undo

ตัวอย่างการทำ Seeder

สร้าง Seeder สำหรับเติมข้อมูลผู้ใช้งานตัวอย่าง

npx sequelize-cli seed:generate --name demo-users

ไฟล์ Seeder จะหน้าตาแบบนี้:

module.exports = {
  up: async (queryInterface) => {
    await queryInterface.bulkInsert('Users', [
      {
        name: 'John Doe',
        email: '[email protected]',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
      {
        name: 'Jane Smith',
        email: '[email protected]',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    ]);
  },
  down: async (queryInterface) => {
    await queryInterface.bulkDelete('Users', null, {});
  },
};

รัน Seeder

เติมข้อมูลใน Database:

npx sequelize-cli db:seed:all

Rollback Seeder

ลบข้อมูลที่ Seeder เคยเพิ่ม:

npx sequelize-cli db:seed:undo

สรุป

Data Migration และ Seeder เป็นเครื่องมือที่ช่วยให้ Developer จัดการ Database structure และข้อมูลใน Database ได้ง่ายขึ้น ไม่ว่าจะเป็นการเพิ่มโครงสร้างใหม่ ลบโครงสร้างเก่า เติมข้อมูล mock หรือ Rollback การเปลี่ยนแปลง ทุกอย่างทำได้ด้วยคำสั่งง่ายๆ

แต่สิ่งสำคัญคือต้องใช้อย่างระมัดระวัง โดยเฉพาะกับระบบ Production เพื่อป้องกันความผิดพลาดที่อาจเกิดขึ้นกับข้อมูลจริง

"ลองเริ่มใช้งาน Migration และ Seeder ในโปรเจกต์ถัดไปของคุณ แล้วคุณจะรู้ว่ามันช่วยประหยัดเวลาได้แค่ไหน!"

Read more

เช็ค Internet จากเว็บ: ทำยังไงให้รู้ว่าออกเน็ตได้จริง?

เช็ค Internet จากเว็บ: ทำยังไงให้รู้ว่าออกเน็ตได้จริง?

เคยเจอไหมครับ เวลาใช้งานเว็บไซต์แล้วอยู่ดี ๆ ก็โหลดข้อมูลไม่ได้ หรือ API เงียบหายไม่มีการตอบกลับ? หลายครั้งเรามักสงสัยว่า "ตกลงปัญหาอยู่ที่ตัวเรา เซิร์ฟเวอร์ หรือ Internet กันแน่?" วันนี้ผมจะมาเล่าเรื่อง "การตรวจสอบสถานะการเชื่อมต่

By maimem
Rust Series #2 - รู้จัก Cargo: ผู้ช่วยส่วนตัวของโปรเจกต์ Rust!

Rust Series #2 - รู้จัก Cargo: ผู้ช่วยส่วนตัวของโปรเจกต์ Rust!

ถ้าคุณเริ่มต้นเขียน Rust แล้วรู้สึกว่า “เฮ้ย! Rust เจ๋งแหะ” ก็ขอแสดงความยินดีครับ คุณเพิ่งเจอเพื่อนแท้ในโลกโปรแกรมมิ่ง! แต่เดี๋ยวก่อน... ถ้าต้องเขียนโค้ดโปรเจกต์ใหญ่ ๆ บริหารไลบรารี ดูแลไฟล์ต่าง ๆ หรือทดสอบโค้ดทุกวั

By maimem
ซ่อน Credential ใน AWS CodeBuild ให้ปลอดภัยด้วย Parameter Store

ซ่อน Credential ใน AWS CodeBuild ให้ปลอดภัยด้วย Parameter Store

ทำไมต้องซ่อน Credential? ในโลกของ DevOps และ Cloud Computing การจัดการ Credential (ข้อมูลรับรอง เช่น API Keys, Passwords, หรือ Secrets ต่างๆ) เป็นเรื่องที่สำคัญอย่างยิ่ง เพราะ Credential เปรียบเสมือนกุญแจที่เปิดประตูไปสู่ทรัพยากรสำคัญในระบบ เช่น ฐานข้อมูล

By maimem
Session ไม่ตาม! เพราะ Load Balancer บน Magento2

Session ไม่ตาม! เพราะ Load Balancer บน Magento2

เมื่อเร็วๆนี้ ผมได้ทำงานเกี่ยวกับพวก Marketplace บน Magento2 ซึ่งเป็นแพลตฟอร์มอีคอมเมิร์ซที่ใช้งานมากในระดับองค์กร โครงสร้างของระบบนี้อยู่บน Server-side architecture ที่ต้องจัดการปัญหาและความท้าทายหลายด้าน โดยเฉพาะการทำให้ระบบ Load Balancer และ Auto Scaling ทำงานได้ราบรื่น เพื่อรองรับจำนวนผู้ใช้งานที่เปลี

By maimem