コアデータベースマイグレーションの管理

このページ

EmDashのコアマイグレーションは、EmDash自体のテーブルとコンテンツテーブルの標準カラムを更新します。コレクションやフィールドの作成、削除、名前変更は行いません。コンテンツモデルの変更については Evolving a Deployed Site を参照してください。

ランタイムマイグレーションモードはデフォルトで auto のため、既存のデプロイメントは起動時に保留中のコアマイグレーションを引き続き適用します。デプロイメント管理マイグレーションでは、新しいアプリケーションコードがトラフィックを受信する前にビルドがデータベースをマイグレーションし、ランタイムがそのデプロイステップを検証または信頼できるようにします。

ビルド、マイグレーション、デプロイ、チェック

Astroのビルドまたは同期で .emdash/migrations.json が書き出されます。このシークレットフリーのマニフェストは、そのビルドで使用された正確なEmDashバージョン、順序付けられたマイグレーションセット、ロケール設定、およびアダプターマイグレーションエグゼキューターを記録します。

マニフェストを生成した依存関係を持つプロジェクトからこれらのコマンドを実行してください。まずビルドしてターゲットを確認します。

pnpm build
pnpm emdash migrate --status

報告されたターゲットが意図したデータベースであることを確認した後、インタラクティブマイグレーションを開始します。確認する前にプロンプトでターゲットを再度確認してください。その後、同じビルドをデプロイし、デプロイされたスキーマを確認します。

pnpm emdash migrate
pnpm wrangler deploy
pnpm emdash migrate --check

emdash migrate --status は、データベースを変更せずに、適用済み、保留中、不明なマイグレーションを報告します。単純な emdash migrate コマンドは、ターゲットを表示し、保留中のマイグレーションを適用する前に確認を求めます。

--check はマイグレーションを適用せず、既知のマイグレーションが保留中であるか、データベースにビルドに不明なマイグレーションレコードが含まれている場合にゼロ以外で終了します。checkの「作業が必要」ゼロ以外の終了ステータスなしで同じマイグレーションセットを確認したい場合は --status を使用してください。CLIリファレンス は、保留中、不明、確認、中断、操作の終了コードを区別しています。

非インタラクティブな適用とすべての --json 適用には --expected-target-fingerprint が必要です。解決されたターゲットが一致しない場合、コマンドは失敗します。これらのオプションは自動デプロイジョブで使用し、上記のインタラクティブワークフローでは使用しないでください。

別の場所に保存されたマニフェストには --manifest path/to/migrations.json を使用してください。ローカル調査には、--from-config [--config astro.config.mjs] がAstroフックの実行やサーバーの起動なしに信頼されたプロジェクト設定を明示的に評価します。デプロイパイプラインはビルドマニフェストを使用すべきです。

データベースを明示的に選択する

設定されたアダプターはシークレットフリーのターゲット情報をマニフェストに提供します。資格情報は環境変数に残り、マイグレーションコマンドのみが読み取ります。

アダプターマニフェストターゲットデフォルト資格情報変数有用なオーバーライド
SQLiteデータベースパスまたは file: URL--database <パス>
libSQLパブリックURLTURSO_AUTH_TOKENmigrationAuthTokenEnv を設定
PostgreSQL接続変数名DATABASE_URL--database-url-env <名前>
Cloudflare D1Wranglerバインディング名CLOUDFLARE_API_TOKEN--d1, --account-id, --wrangler-config, --wrangler-env
Hyperdriveプライマリバインディングとオリジン変数名バインディング固有のダイレクトオリジン変数migrationConnectionStringEnv を設定

相対SQLiteパスはプロジェクトルートから解決されます。インストールされたEmDashパッケージやシェルの現在のサブディレクトリからではありません。PostgreSQL、libSQL、Hyperdriveのターゲットラベルは資格情報とURLパラメーターを省略します。

マイグレーション前にD1をプロビジョニングする

D1データベースの作成とそのスキーマのマイグレーションは別の操作です。emdash migrate は存在しないデータベースを作成しません。

  1. データベースをプロビジョニングし、そのプロダクションUUIDを記録します。

    pnpm wrangler d1 create my-site-production
  2. そのUUIDを wrangler.jsonc の意図したバインディングと環境に追加します。

  3. D1バインディングが .emdash/migrations.json に記録されるようにサイトをビルドします。

  4. アカウントIDとD1編集権限を持つスコープ付きトークンを設定します。選択したターゲットを確認し、インタラクティブマイグレーションを実行します。アカウントとデータベースが意図したプロダクションデータベースと一致する場合のみプロンプトを確認してください。

    export CLOUDFLARE_ACCOUNT_ID="..."
    export CLOUDFLARE_API_TOKEN="..."
    pnpm emdash migrate \
      --status \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production
    pnpm emdash migrate \
      --wrangler-config wrangler.jsonc \
      --wrangler-env production

代わりに --account-id--d1 <データベースUUIDまたは名前> を指定できます。名前検索は正確に1つのデータベースに解決される必要があります。プレビューID、プレースホルダーID、競合するアカウント、曖昧なバインディングはクローズドで失敗します。

CIでD1マイグレーションを設定する

D1はPostgreSQLが使用するアドバイザリーマイグレーションロックを提供しません。アカウントとデータベースUUIDごとに最大1つのマイグレーションジョブを実行してください。

CI環境で以下のシークレットと変数を設定してください:

  • シークレット CLOUDFLARE_API_TOKEN:D1編集権限を持つスコープ付きトークン。
  • 変数 CLOUDFLARE_ACCOUNT_ID:データベースを所有するCloudflareアカウントID。
  • 変数 D1_DATABASE_ID:プロダクションD1データベースUUID。
  • 変数 EMDASH_TARGET_FINGERPRINT:ローカルでアカウントとデータベースを確認した後に emdash migrate --status が出力するフィンガープリント。

以下のGitHub Actionsワークフローはこれらの値を使用し、同時実行グループを両方の不変D1識別子にキーイングします。適用ステップは非インタラクティブなので、確認済みのターゲットフィンガープリントを明示的に提供します。

name: Deploy

on:
  workflow_dispatch:

concurrency:
  group: emdash-migrations-${{ vars.CLOUDFLARE_ACCOUNT_ID }}-${{ vars.D1_DATABASE_ID }}
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - name: Inspect EmDash migration target
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --status --json \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"
      - name: Apply EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          EMDASH_TARGET_FINGERPRINT: ${{ vars.EMDASH_TARGET_FINGERPRINT }}
        run: |
          pnpm emdash migrate \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}" \
            --expected-target-fingerprint "$EMDASH_TARGET_FINGERPRINT"
      - run: pnpm wrangler deploy
      - name: Check EmDash migrations
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        run: |
          pnpm emdash migrate --check \
            --account-id "${{ vars.CLOUDFLARE_ACCOUNT_ID }}" \
            --d1 "${{ vars.D1_DATABASE_ID }}"

EMDASH_TARGET_FINGERPRINT は、変更されたターゲットをローカルで確認した後にのみ更新してください。フィンガープリントには資格情報は含まれませんが、アカウントとデータベースを確認せずに変更すると、間違ったデータベースのマイグレーションに対する保護が失われます。

Hyperdriveはオリジンに接続する

Hyperdriveのマイグレーションエグゼキューターはオリジンへの直接PostgreSQL接続を開きます。Hyperdriveを介してマイグレーショントラフィックを送信せず、オプションのキャッシュバインディングを使用せず、Workerからのプライベートネットワーク到達性を継承しません。

デプロイランナーはオリジンに到達できる必要があります。デフォルトのバインディング固有の変数が不適切な場合は、hyperdrive()migrationConnectionStringEnv を設定し、その変数はマイグレーションジョブにのみ提供してください。ランタイムのHyperdrive資格情報とダイレクトオリジンデプロイ資格情報を分離してください。

ランタイム適用を段階的に導入する

以下のEmDashインテグレーション設定は、開発環境での自動マイグレーションを維持しつつ、ランタイム適用を有効にします。

emdash({
	database,
	migrations: {
		runtime: "check",
		dev: "auto",
	},
});
  • auto は後方互換性のあるデフォルトです。ランタイムは起動時に保留中のマイグレーションをチェックして適用します。
  • check は方向性のあるステータスクエリを実行し、既知のマイグレーションが保留中の場合にリクエストを処理する前に503を返します。ローリングデプロイ中のより新しい互換ビルドからのレコードを許容します。
  • manual はランタイムでのマイグレーションやステータスクエリを実行しません。デプロイパイプラインがすべてのビルドを確実に適用・チェックするようになった後にのみ使用してください。

EMDASH_MIGRATIONS_MODE は、同じアーティファクトが複数の環境を通じてプロモートされる場合にランタイムモードをオーバーライドできます。セットアップおよび開発バイパスルートは有効なモードに従います。checkmanual の背後で暗黙的にマイグレーションすることはできません。

保守的なロールアウトは、デプロイジョブの導入中は auto、ジョブが信頼できるようになったら check、すべてのデプロイに外部チェックが適用されるようになったら manual です。

ローリングデプロイ中の互換性

コアマイグレーションはexpand/deploy/contractシーケンスに従います。デプロイは一時的に古いアプリケーションアイソレートと新しいアプリケーションアイソレートを拡張されたデータベースに対して実行する場合があり、バックフィルがまだ進行中の場合があります。すべてのデプロイされたバージョンがスキーマの使用を停止するまでコントラクトしないでください。

不明な適用済みマイグレーションレコードは、このローリングデプロイ方向に対してのみランタイム check で許容されます。CLIの正確なチェックはそれらを報告し、applyは変更を拒否します。データベースがより新しいか、分岐したマイグレーション履歴を持っている可能性があるためです。

トラブルシューティング

  • マイグレーションマニフェストが見つかりません。 まずプロジェクトをビルドまたは同期してください。非標準のアーティファクトの場所には --manifest を、ローカル調査には明示的に --from-config を選択してください。
  • アーティファクトがプロジェクトのEmDashと一致しません。 アプリケーションとマニフェストを一緒にリビルドしてデプロイしてください。グローバルインストールではなくプロジェクトのCLIを実行してください。
  • ターゲットが見つからないか曖昧です。 まずプロビジョニングし、明示的なデータベースパス、接続変数名、D1セレクター、または選択したWrangler設定と環境を指定してください。EmDashは無関係な環境変数やバインディングから推測しません。
  • ターゲットのフィンガープリントが変更されました。 停止して、表示されたアカウント、環境、データベース名、UUID、またはパスを確認してください。意図したターゲットを確認した後にのみ期待されるフィンガープリントを更新してください。
  • 不明なマイグレーションレコードが存在します。 レコードを削除したりapplyを再実行したりしないでください。アプリケーションアーティファクトが意図したバージョンであることを確認し、より新しいまたは分岐したビルドがデータベースをマイグレーションしたかどうかを調査してください。
  • D1書き込み結果が曖昧です。 マイグレーションコマンドを再実行しないでください。同じアカウントとデータベースUUIDに対して emdash migrate --status を実行し、結果を確認し、マイグレーションが途中で停止した場合はエスカレートしてください。
  • Hyperdriveが接続できません。 デプロイランナーからPostgreSQLオリジンへの到達性をテストし、ダイレクトオリジン変数を確認してください。Worker対Hyperdriveの接続性は、ランナーがオリジンに到達できることを証明しません。