Migration
Migration は NocoBase のデータマイグレーション基底クラスで、プラグインのアップグレード時にデータベース構造の変更やデータマイグレーションを処理するために使用します。@nocobase/server からインポートします。
import { Migration } from '@nocobase/server';
export default class extends Migration {
on = 'afterLoad';
appVersion = '<1.0.0';
async up() {
// アップグレードロジック
}
}
クラスプロパティ
on
on: 'beforeLoad' | 'afterSync' | 'afterLoad';
upgrade フロー内での migration の実行タイミングを制御します。デフォルトは 'afterLoad' です。
appVersion
semver 範囲文字列で、どのバージョンのアプリケーションで migration を実行するかを決定します。フレームワークは semver.satisfies() で判定します:現在のアプリケーションバージョンがこの範囲を満たす場合のみ、migration が実行されます。
// 1.0.0 未満のバージョンからアップグレードする場合のみ実行
appVersion = '<1.0.0';
// 0.21.0-alpha.13 未満のバージョンからアップグレードする場合のみ実行
appVersion = '<0.21.0-alpha.13';
// 空にすると毎回の upgrade で実行
appVersion = '';
インスタンスプロパティ
app
NocoBase Application インスタンスです。これを通じてアプリケーションの各モジュールにアクセスできます:
async up() {
// アプリケーションバージョンを取得
const version = this.app.version;
// ログを取得
this.app.log.info('Migration started');
}
db
NocoBase Database インスタンスです。Repository の取得やクエリの実行などに使用できます:
async up() {
const repo = this.db.getRepository('users');
await repo.update({
filter: { status: 'inactive' },
values: { status: 'disabled' },
});
}
plugin
現在のプラグインインスタンスです。プラグインレベルの migration でのみ利用可能です(core migration では undefined)。
async up() {
const pluginName = this.plugin.name;
}
sequelize
get sequelize(): Sequelize
Sequelize インスタンスです。生の SQL を直接実行できます:
async up() {
await this.sequelize.query(`UPDATE users SET status = 'active' WHERE status IS NULL`);
}
queryInterface
get queryInterface(): QueryInterface
Sequelize QueryInterface です。DDL 操作(カラムの追加/削除、制約の追加、カラム型の変更など)に使用します:
async up() {
const { DataTypes } = require('@nocobase/database');
// カラムを追加
await this.queryInterface.addColumn('users', 'nickname', {
type: DataTypes.STRING,
});
// ユニーク制約を追加
await this.queryInterface.addConstraint('users', {
type: 'unique',
fields: ['email'],
});
}
pm
プラグインマネージャーです。this.pm.repository を通じてプラグインのメタデータをクエリおよび変更できます:
async up() {
const plugins = await this.pm.repository.find();
for (const plugin of plugins) {
// プラグインレコードを一括変更
}
}
インスタンスメソッド
up()
async up(): Promise<void>
アップグレード時に実行されます。 サブクラスはこのメソッドをオーバーライドし、マイグレーションロジックを記述する必要があります。
down()
async down(): Promise<void>
ロールバック時に実行されます。 ほとんどの migration では空のままにします。ロールバックをサポートする必要がある場合は、ここに逆操作を記述します。
完全な例
Repository API を使用してデータを更新する(afterLoad)
最も一般的なシーン -- すべてのプラグインのロード完了後に、Repository API でデータを一括更新します:
import { Migration } from '@nocobase/server';
export default class extends Migration {
appVersion = '<1.0.0';
async up() {
const repo = this.db.getRepository('roles');
await repo.update({
filter: {
$or: [{ allowConfigure: true }, { name: 'root' }],
},
values: {
snippets: ['ui.*', 'pm', 'pm.*'],
allowConfigure: false,
},
});
}
async down() {}
}
QueryInterface を使用してテーブル構造を変更する(beforeLoad)
プラグインのロード前に低レベルの DDL を実行します -- 例えばテーブルに新しいカラムとユニーク制約を追加します:
import { DataTypes } from '@nocobase/database';
import { Migration } from '@nocobase/server';
export default class extends Migration {
on = 'beforeLoad';
appVersion = '<0.14.0-alpha.2';
async up() {
const tableName = this.pm.collection.getTableNameWithSchema();
const field = this.pm.collection.getField('packageName');
// フィールドが既に存在するか確認
const exists = await field.existsInDb();
if (exists) return;
await this.queryInterface.addColumn(tableName, field.columnName(), {
type: DataTypes.STRING,
});
await this.queryInterface.addConstraint(tableName, {
type: 'unique',
fields: [field.columnName()],
});
}
}
生の SQL を使用する(afterSync)
テーブル構造の同期完了後に、生の SQL でデータマイグレーションを行います:
import { Migration } from '@nocobase/server';
export default class extends Migration {
on = 'afterSync';
appVersion = '<1.0.0-alpha.3';
async up() {
const items = await this.pm.repository.find();
for (const item of items) {
if (item.name.startsWith('@nocobase/plugin-')) {
item.set('name', item.name.substring('@nocobase/plugin-'.length));
await item.save();
}
}
}
}
Migration ファイルの作成
CLI コマンドで作成します:
yarn nocobase create-migration my-migration --pkg @my-project/plugin-hello
コマンドはプラグインの src/server/migrations/ ディレクトリにタイムスタンプ付きのファイルを生成します。テンプレートは以下の通りです:
import { Migration } from '@nocobase/server';
export default class extends Migration {
on = 'afterLoad';
appVersion = '<現在のバージョン>';
async up() {
// coding
}
}
コマンドパラメータ:
関連リンク