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 လုပ်ရပါသည်။
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.tsIDatabaseMigration
getName()၊ up()၊ down() နှင့် getSource() ကို implement လုပ်ရပါသည်။ getSource() က ပြောင်းလဲမှု ပိုင်ဆိုင်သော datasource (များသောအားဖြင့် plugin: "default") ကို ဖော်ပြပါသည်။
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() ကို အသုံးပြုနိုင်ပါသည်။
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 အစဉ်
- 01
Plugin install / upgrade
Core က module.js ကို load လုပ်ပြီး getMigrations() ကို ဖတ်ပါသည်။
- 02
Pending migration များ သက်ရောက်ခြင်း
မသုံးရသေးသော getName() တိုင်းအတွက် getSource() ပေါ်တွင် up(queryRunner) ကို run လုပ်ပါသည်။
- 03
onMigrate()
Migration batch ပြီးဆုံးပြီးနောက် optional plugin hook ဖြစ်ပါသည်။
- 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 နှင့် ကိုက်ညီအောင် ထားရပါသည်