skipLink.label

Database Migration Assistant

Database Migration Assistant

hard 30-45 minutes

🎯 Learning Objectives

  • ✅ How to generate forward (UP) and rollback (DOWN) SQL migration scripts
  • ✅ Why every migration MUST have a rollback — deploying without one is dangerous
  • ✅ How to handle add_column, drop_column, and rename_column operations
  • ✅ The principle of migrating forward: never deploy without a rollback plan

📖 Concept: Database Schema Migrations

Database migration คือการเปลี่ยนแปลง schema ของ database อย่างมีแบบแผน — เหมือนการเปลี่ยนแปลงท่าไม้ตายของนักสู้ที่ต้องทำอย่างระมัดระวัง ทุกการเปลี่ยนแปลงต้องมี forward migration (ทำ) และ rollback (ย้อนกลับ)

หลักการสำคัญ: MIGRATE FORWARD, ROLLBACK ALWAYS — ทุก schema change ต้องมีทางถอย. AI tools มักจะ generate แค่ UP SQL แล้วลืม DOWN SQL ซึ่งอันตรายมาก — ถ้า migration fail คุณจะไม่มีทางย้อนกลับ

Think of it like learning a new technique — you must also learn how to safely undo it if it doesn’t work. A martial artist who can only attack but never retreat is dangerous to themselves.

⚙️ How It Works

The Migration Generation Workflow

  1. Parse changes — extract operation type, table, column, data type
  2. Generate UP SQL — the forward migration
  3. Generate DOWN SQL — the rollback (MUST be generated too)
  4. Verify both — ensure UP and DOWN are both non-empty

Operation Mapping

// add_column: ADD in UP, DROP in DOWN
{ type: 'add_column', table: 'users', column: 'email', dataType: 'VARCHAR(255)' }
// UP: ALTER TABLE users ADD COLUMN email VARCHAR(255);
// DOWN: ALTER TABLE users DROP COLUMN email;
// drop_column: DROP in UP, ADD in DOWN
{ type: 'drop_column', table: 'users', column: 'legacy_id' }
// UP: ALTER TABLE users DROP COLUMN legacy_id;
// DOWN: ALTER TABLE users ADD COLUMN legacy_id <type>;
// rename_column: RENAME in UP, reverse in DOWN
{ type: 'rename_column', table: 'users', column: 'name', newColumn: 'full_name' }
// UP: ALTER TABLE users RENAME COLUMN name TO full_name;
// DOWN: ALTER TABLE users RENAME COLUMN full_name TO name;

The Critical Rule: DOWN SQL Must Not Be Empty

// ❌ Naive AI output
{ up: 'ALTER TABLE users ADD COLUMN email VARCHAR(255);', down: '' }
// ✅ Correct output
{
up: 'ALTER TABLE users ADD COLUMN email VARCHAR(255);',
down: 'ALTER TABLE users DROP COLUMN email;'
}

💡 Example: Walkthrough

const changes = [
{ type: 'add_column', table: 'users', column: 'email', dataType: 'VARCHAR(255)' },
{ type: 'drop_column', table: 'users', column: 'legacy_id' }
];
// Generated migration:
{
up: `ALTER TABLE users ADD COLUMN email VARCHAR(255);
ALTER TABLE users DROP COLUMN legacy_id;`,
down: `ALTER TABLE users DROP COLUMN email;
ALTER TABLE users ADD COLUMN legacy_id <type>;`
}

⚠️ Common Mistakes

Mistake 1: Leaving DOWN SQL empty

“UP SQL ถูกต้องแล้ว → deploy เลย” → ทุก migration ต้องมี DOWN SQL — ไม่มี rollback = ไม่ deploy

Mistake 2: Not handling rename rollback

“Rename column → UP ถูกต้อง แต่ DOWN ลืม reverse” → Rollback ของ rename คือ rename กลับ: full_name → name

Mistake 3: Losing table name

“ลืมใส่ table name ใน SQL” → ทุก ALTER TABLE ต้องระบุ table name อย่างชัดเจน

Mistake 4: Empty changes crashes

“ไม่ได้ handle changes ว่าง” → Empty changes → return { up: '', down: '' }

📝 Knowledge Check

📝 Knowledge Check

Q1:What must every database migration include?

Q2:What is the rollback SQL for an `add_column` operation?

Q3:Why do naive AI tools often leave DOWN SQL empty?

🏋️ Quest: Database Migration Assistant

Now it’s time to practice! Generate schema migration scripts.

  1. Download ไฟล์เริ่มต้นของ quest:

    Terminal window
    npx bluebeltdojo download quest-99-db-migration
    cd quest-99-db-migration
  2. เปิด problem.js ใน editor ของคุณพร้อมความช่วยเหลือของ AI

  3. Implement solution ตาม instructions ใน problem.js

  4. ตรวจสอบ solution ของคุณ:

    Terminal window
    node test.js
  5. ส่งคำตอบ:

    Terminal window
    npx bluebeltdojo submit

💡 Tip: ทดสอบ edge case — DOWN SQL ต้องไม่ว่างเปล่าเสมอ

คำใบ้

  • generateMigration(changes) รับ array ของ schema changes และ return { up, down }
  • ทุก change ต้อง generate ทั้ง UP และ DOWN SQL
  • add_column → UP: ADD, DOWN: DROP
  • drop_column → UP: DROP, DOWN: ADD
  • rename_column → UP: RENAME TO, DOWN: RENAME BACK
  • ถ้าติดขัด ดู _solution/solution.js