mcpField
C
convex-migration-helper

convex-migration-helper

github.com/get-convexデータ・データベース6993.8k 回インストール1 日前に更新
リポジトリ

convex-migration-helper について

Convex のスキーマ変更と既存データ移行を安全に進めるスキルで、破壊的変更を扱う開発者向けです。スキーマの拡張、データのバッチ移行、スキーマの縮小という流れを示し、ドライランと検証も案内します。

主な機能

  1. 01複数回デプロイする移行手順
  2. 02オンライン移行のガイド
  3. 03@convex-dev/migrations によるバッチ処理
  4. 04ドライランと進捗監視
  5. 05一般的なスキーマ変更パターン

活用シーン

  1. 01既存ドキュメントへの必須フィールド追加
  2. 02フィールド型やテーブル構造の変更
  3. 03既存データの分割や統合
  4. 04フィールドの改名や非推奨化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/get-convex/agent-skills --skill convex-migration-helper

インストール後、Claude Code で/convex-migration-helperを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
assets/
icon.svg
references/
migration-patterns.md
migrations-component.md

詳細

Convex 移行ヘルパー

破壊的変更を行う際に、Convex のスキーマとデータを安全に移行します。

使用する場面

  • 既存のテーブルに新しい必須フィールドを追加するとき
  • フィールドの型や構造を変更するとき
  • テーブルを分割または統合するとき
  • フィールドの名前を変更または削除するとき
  • ネストされたデータからリレーショナルデータに移行するとき

使用しない場面

  • 本番環境または開発環境に既存データがない新規スキーマの場合
  • バックフィルが不要なオプションフィールドを追加するとき
  • 移行対象の既存データがない新しいテーブルを追加するとき
  • 正確性に懸念のないインデックスを追加または削除するとき
  • 移行の必要がない Convex のスキーマ設計に関する質問の場合

重要な概念

スキーマ検証がワークフローを決定します

Convex では、保存済みデータと一致しないスキーマをデプロイできません。 これがすべての移行を左右する基本的な制約です。

  • 既存のドキュメントにフィールドがない場合、必須フィールドを追加できません
  • 既存のドキュメントに古い型のフィールドがある場合、フィールドの型を変更できません
  • 既存のドキュメントにフィールドが残っている場合、スキーマからそのフィールドを削除できません

つまり、移行は予測可能なパターンに従います。スキーマを拡張し、データを移行してから、スキーマを縮小します。

オンライン移行

Convex の移行はオンラインで実行されます。つまり、データが非同期のバッチで更新されている間も、アプリはリクエストを処理し続けます。移行期間中、コードでは古い形式と新しい形式の両方に対応する必要があります。

型の変更より新しいフィールドを優先する

データの形を変更する場合は、既存のフィールドを変更するのではなく、新しいフィールドを作成してください。これにより、より安全でロールバックしやすい移行になります。

データを削除しない

確信がない限り、フィールドを削除するのではなく、非推奨にすることを優先してください。フィールドを v.optional としてマークし、非推奨であることと、そのフィールドが存在していた理由を説明するコードコメントを追加します。

安全な変更(移行不要)

オプションフィールドの追加
// Before
users: defineTable({
  name: v.string(),
});

// After - safe, new field is optional
users: defineTable({
  name: v.string(),
  bio: v.optional(v.string()),
});
新しいテーブルの追加
posts: defineTable({
  userId: v.id("users"),
  title: v.string(),
}).index("by_user", ["userId"]);
インデックスの追加
users: defineTable({
  name: v.string(),
  email: v.string(),
}).index("by_email", ["email"]);

破壊的変更:デプロイワークフロー

破壊的な移行はすべて、同じ複数回のデプロイパターンに従います。

デプロイ 1 — スキーマを拡張する:

  1. 古い形式と新しい形式の両方を許可するようにスキーマを更新します(例:新しいオプションフィールドを追加)
  2. 読み取り時に両方の形式を処理できるよう、コードを更新します
  3. 新しいドキュメントには新しい形式を書き込むよう、コードを更新します
  4. デプロイします

デプロイの間 — データを移行する:

  1. 既存のドキュメントをバックフィルする移行を実行します
  2. すべてのドキュメントが移行されたことを確認します

デプロイ 2 — スキーマを縮小する:

  1. 新しい形式のみを必須にするよう、スキーマを更新します
  2. 古い形式を処理するコードを削除します
  3. デプロイします

Migrations コンポーネントの使用

複雑な移行には、@convex-dev/migrations コンポーネントを使用してください。バッチ処理、カーソルベースのページネーション、状態追跡、失敗からの再開、ドライラン、進捗の監視に対応しています。

インストール、セットアップ、npx convex run migrations:myMigration による移行の直接定義と実行、ドライラン、ステータスの監視、設定オプションについては、references/migrations-component.md を参照してください。

一般的な移行パターン

コード例を含む完全なパターンについては、references/migration-patterns.md を参照してください。以下を取り上げています。

  • 必須フィールドの追加
  • フィールドの削除
  • フィールドの型の変更
  • ネストされたデータの別テーブルへの分割
  • 孤立したドキュメントのクリーンアップ
  • ゼロダウンタイム戦略(デュアル書き込み、デュアル読み取り)
  • 小規模なテーブル向けの簡易策(コンポーネントを使わない単一の internalMutation)
  • 移行が完了したことの確認

よくある落とし穴

  1. データ移行の前にフィールドを必須にすること:既存のドキュメントにフィールドがないため、Convex はデプロイを拒否します。まず必ずスキーマを緩和してください。
  2. 大きなテーブルで .collect() を使うこと:トランザクションの上限に達したり、タイムアウトが発生したりします。適切なバッチ処理付きページネーションには、migrations コンポーネントを使ってください。.collect() を使っても安全なのは、小さいとわかっているテーブルだけです。
  3. 移行前に新しい形式で書き込まないこと:移行期間中に作成されたドキュメントが見落とされ、移行が「完了」した後も移行されていないデータが残ります。
  4. ドライランを省略すること:本番データに変更を適用する前に、dryRun: true を使って移行ロジックを検証してください。実際のドキュメントに影響する前にバグを検出できます。
  5. フィールドを早まって削除すること:コメントを付けて v.optional で非推奨にする方法をおすすめします。データが不要になり、そのフィールドを参照するコードがないと確信できてから削除してください。
  6. 移行バッチに crons を使うこと:migrations コンポーネントは、再帰的なスケジューリングによって内部でバッチ処理を行います。crons を使う場合は手動でのクリーンアップが必要で、削除するために追加のデプロイも必要になります。

移行チェックリスト

  • 破壊的変更を特定し、複数回に分けたデプロイのワークフローを計画する
  • 古い形式と新しい形式の両方を許可するようにスキーマを更新する
  • 読み取り時に両方の形式を処理できるようコードを更新する
  • 新しいドキュメントには新しい形式で書き込むようコードを更新する
  • 拡張したスキーマと更新したコードをデプロイする
  • @convex-dev/migrations コンポーネントを使って移行を定義する
  • npx convex run migrations:myMigration '{"dryRun": true}' を使ってテストする
  • npx convex run migrations:myMigration で移行を直接実行し、 状態を監視する
  • すべてのドキュメントが移行されたことを確認する
  • 新しい形式のみを必須にするようスキーマを更新する
  • 古い形式を処理するコードをクリーンアップする
  • 最終的なスキーマとコードをデプロイする
  • 安定性を確認したら移行コードを削除する

コメント