Demo

Migrations

Schema ပြောင်းလဲမှုများကို IPlugin.getMigrations() ဖြင့် ပေးပို့ရပါသည် — auto-sync ကို မမှီခိုရပါ။ Migration တစ်ခုစီသည် QueryRunner ပေါ်တွင် up/down ပါသော IDatabaseMigration ဖြစ်ပါသည်။

Migration မည်သည့်အခါ သုံးမည်

Entity registration က runtime အတွက် ဇယားများကို ကြေညာနေသေးသော်လည်း၊ အမှန် schema ပြောင်းလဲမှုအတွက် migration ကို ဦးစားပေးရပါသည်။ Production upgrade တွင် synchronize ကို မမှီခိုရပါ။

  • Column၊ index၊ constraint၊ rename စသည့် schema ပြောင်းလဲမှုများ
  • Plugin upgrade အတွင်း တစ်ကြိမ်သာ run ရမည့် data backfill များ
  • Staging / production တွင် ပြန်လှန်နိုင်ရမည့် အရာများ

Folder အပြင်အဆင်

Migration class များကို backend/src/migrations/ (သို့မဟုတ် backend/migrations/) အောက်တွင် ထားရှိရပါသည်။ getMigrations() ပြန်ပေးနိုင်ရန် plugin entry မှ export လုပ်ရပါသည်။

TSlayout
1backend/ 2 src/ 3 index.ts # IPlugin — getMigrations() 4 migrations/ 5 001-initial.migration.ts 6 002-add-status.migration.ts 7 feature/ 8 my.module.ts

IDatabaseMigration

getName()၊ up()၊ down() နှင့် getSource() ကို implement လုပ်ရပါသည်။ getSource() က ပြောင်းလဲမှု ပိုင်ဆိုင်သော datasource (များသောအားဖြင့် plugin: "default") ကို ဖော်ပြပါသည်။

TSXmigration
1import type { IDatabaseMigration } from "@quan-erp/shared-types"; 2import type { QueryRunner } from "typeorm"; 3import metadata from "../../module.metadata.json" with { type: "json" }; 4 5export class AddStatusMigration implements IDatabaseMigration { 6 getName() { 7 return `${metadata.name}_002_add_status`; 8 } 9 10 getSource() { 11 return { plugin: "default", name: "default" }; 12 } 13 14 async up(queryRunner: QueryRunner): Promise<void> { 15 await queryRunner.query( 16 `ALTER TABLE ${metadata.name}_order ADD COLUMN IF NOT EXISTS status varchar(32)` 17 ); 18 } 19 20 async down(queryRunner: QueryRunner): Promise<void> { 21 await queryRunner.query( 22 `ALTER TABLE ${metadata.name}_order DROP COLUMN IF EXISTS status` 23 ); 24 } 25}

IPlugin တွင် မှတ်ပုံတင်ခြင်း

backend/src/index.ts ၏ default-exported plugin class မှ getMigrations() ဖြင့် migration class များကို ပြန်ပေးရပါသည်။ လိုအပ်ပါက post-migration hook အတွက် onMigrate() ကို အသုံးပြုနိုင်ပါသည်။

TSXbackend/src/index.ts
1import type { GetMigrationsType, IPlugin } from "@quan-erp/shared-types"; 2import { InitialMigration } from "./migrations/001-initial.migration.js"; 3import { AddStatusMigration } from "./migrations/002-add-status.migration.js"; 4 5export default class MyPlugin implements IPlugin { 6 getMigrations(): GetMigrationsType { 7 return [InitialMigration, AddStatusMigration]; 8 } 9 10 async onMigrate(): Promise<void> { 11 // optional: seed / repair after migrations apply 12 } 13 14 // … getRootModule, getName, getVersion, getMetadata, … 15}

Run အစဉ်

  1. 01

    Plugin install / upgrade

    Core က module.js ကို load လုပ်ပြီး getMigrations() ကို ဖတ်ပါသည်။

  2. 02

    Pending migration များ သက်ရောက်ခြင်း

    မသုံးရသေးသော getName() တိုင်းအတွက် getSource() ပေါ်တွင် up(queryRunner) ကို run လုပ်ပါသည်။

  3. 03

    onMigrate()

    Migration batch ပြီးဆုံးပြီးနောက် optional plugin hook ဖြစ်ပါသည်။

  4. 04

    Module init

    Entities၊ DI နှင့် @OnInit သည် ပုံမှန်အတိုင်း ဆက်လက် လုပ်ဆောင်ပါသည်။

အကောင်းဆုံး အလေ့အထများ

  • Migration name များကို metadata.name ဖြင့် prefix လုပ်ရပါသည် — plugin အားလုံးတွင် unique ဖြစ်စေရန်
  • up/down ကို တွဲထားရပါသည်; down သည် တူညီသော ပြောင်းလဲမှုကို ပြန်ဖျက်ရပါမည်
  • Local/dev တွင် ဘေးကင်းစွာ ပြန် run ရန် IF EXISTS / IF NOT EXISTS (သို့မဟုတ် တူညီသော check) ကို ဦးစားပေးရပါသည်
  • Ship ပြီးသား migration ကို မပြင်ရပါ — နံပါတ်အသစ်ဖြင့် migration အသစ် ထည့်ရပါသည်
  • Entity definition များကို migration များက ထုတ်ပေးသော နောက်ဆုံး schema နှင့် ကိုက်ညီအောင် ထားရပါသည်