EmDash は、コレクション、フィールド、タクソノミーを、コンテンツと並べてデータベースに保存します。このガイドでは、稼働中のコンテンツモデルを変更する方法を説明します。コードのデプロイ、初回のシード、EmDash コアのマイグレーションと混同しないようにしてください。例では Cloudflare D1 を使いますが、同じ区別はすべてのデータベースアダプターに当てはまります。
何が何を変更するか
サイトは 4 つの異なるワークフローを経ます。それぞれが別のレイヤーに作用します。
| ワークフロー | 変更されるもの | 方法 |
|---|---|---|
| コンテンツの編集 | エントリー、メディア、設定 | 管理パネルまたはコンテンツ API |
| コードのデプロイ | テンプレート、設定、EmDash のバージョン | wrangler deploy — EmDash が管理するデータベーステーブルをマイグレーションする場合があります |
| 初回ブートストラップ | 空の状態からすべて | マイグレーション + シードファイル + セットアップウィザード(初回起動時に自動) |
| スキーマの進化 | コレクション、フィールド、タクソノミー | 管理パネル、または稼働中のサイトに対する emdash schema(このページ) |
シードファイルが関わるのは 3 行目だけです。そのスキーマと構造は、セットアップウィザードが完了する前の最初のリクエストで 1 回だけ適用されます。変更したシードファイルを既存のデータベースに対してデプロイしても何も起こりません。稼働中のサイトのスキーマを進化させるには、常に管理パネルまたは API を使います。
管理画面でスキーマを変更する
デプロイ済みサイトを進化させる主な方法は、管理パネルです。管理画面で Content Types を開き、コレクションとフィールドを追加、編集、削除します。変更はすぐに反映されます。コンテンツ API、ローダー、編集 UI は、いずれも実行時にデータベースからスキーマを読み取るためです。
利用できるフィールドタイプ、検証ルール、ウィジェットオプションについては、コレクションとフィールドを参照してください。
スキーマを変更したら、テンプレートで使用する TypeScript の型を再生成します。emdash types コマンドは稼働中のインスタンスからスキーマを読み取るため、デプロイ済みサイトを直接指定できます。
npx emdash types --url https://example.com
CLI からスキーマを変更する
emdash schema コマンドは、REST API を通じて稼働中のインスタンスと通信するため、ローカル開発と同じようにデプロイ済みサイトに対しても動作します。デバイスフローで一度だけ認証します。
npx emdash login --url https://example.com
別の方法として、管理画面の Settings → API Tokens で API トークンを作成し、--token または EMDASH_TOKEN 環境変数で渡すこともできます。CI で便利です。
そのあとは、ローカルで使うのと同じコマンドでスキーマを進化させます。
npx emdash schema add-field posts subtitle --type string --label "Subtitle" --url https://example.com
npx emdash schema remove-field posts legacy_field --url https://example.com
npx emdash schema create projects --label Projects --url https://example.com
これらのコマンドはスクリプトにまとめてチェックインでき、各環境が同じ順序の変更を受け取れます。ただし、コマンドは自動的には冪等になりません。すでに存在するオブジェクトに対して create や add-field を再実行すると、失敗する場合があります。emdash schema list や get で対象を確認し、どの環境がどの手順を完了したかを記録し、最初のエラーで止めてください。
コマンドの全一覧は、CLI リファレンスを参照してください。
シードファイルを同期する
ビルドに埋め込まれたシードファイルは、新規のデータベースがどのように初期化されるかを決めます。新しいプレビュー環境、障害復旧のための再構築、同じサイトの 2 つ目のデプロイなどが該当します。本番環境が別のものへ進化したのに、シードがいまだにスターターブログを記述している場合、新しい環境はすべて誤ったモデルでブートストラップされます。
ビルドは、.emdash/seed.json、package.json#emdash.seed のパス、seed/seed.json のうち、最初に見つかったシードファイルを埋め込みます。どれも存在しない場合は、組み込みのデフォルトシード(スターターブログのモデル)が埋め込まれ、astro dev は警告をログに出力します。
デプロイ済みサイトのスキーマを進化させたら、稼働中のモデルをリポジトリにエクスポートし直します。emdash export-seed はローカルの SQLite ファイルを読み取ります。オフサイト D1 ダンプを作成するの説明に従って SQL ファイルを作成し、テーブルと行をローカルデータベースに読み込んで、シードをエクスポートします。
sqlite3 prod.db < backup-schema.sql
sqlite3 prod.db < backup-folders.sql
sqlite3 prod.db < backup-data.sql
npx emdash export-seed --database prod.db > .emdash/seed.json
エクスポートされたシードには、稼働中のサイトの設定、コレクション、タクソノミー、メニュー、リダイレクト、ウィジェットエリア、セクションが含まれます。エントリーも含めるには --with-content を追加します。新しいスキーマに依存するコードと一緒に、更新した .emdash/seed.json をコミットしてください。これにより、新しい環境は常に、コードが理解できるモデルでブートストラップされます。
プレビュー環境で変更をリハーサルする
破壊的なスキーマ変更(フィールドの削除、コレクションの再構成)は、本番環境の使い捨てコピーに対してリハーサルするのが最も安全です。
-
プレビュー用の D1 データベースを別に作成し、Wrangler に
preview環境へ追加させます。npx wrangler d1 create emdash-db-preview \ --binding DB --env preview --update-configenv.preview.d1_databasesに、新しいデータベース名と UUID が含まれていることを確認します。バインディングは、最上位の Wrangler 設定から継承されません。 -
オフサイト D1 ダンプを作成するの説明に従って、本番環境から SQL ファイルを作成し、プレビュー環境の
DBバインディングを通じて順番にインポートします。npx wrangler d1 execute DB --env preview --remote --file=./backup-schema.sql npx wrangler d1 execute DB --env preview --remote --file=./backup-folders.sql npx wrangler d1 execute DB --env preview --remote --file=./backup-data.sql npx wrangler d1 execute DB --env preview --remote --file=./backup-indexes.sqlプレビューサイトは、そのセクションで説明しているとおり、検索 API が最初に呼び出されたときに検索インデックスを再構築します。
-
プロジェクトをビルドしてプレビュー環境にデプロイし、プレビュー URL に対してスキーマ変更を実行します。
npm run build npx wrangler deploy --env preview npx emdash schema remove-field posts legacy_field --url https://preview.example.com -
公開ページ、管理画面のフォーム、生成された型、変更したフィールドを読み取るすべてのテンプレートを確認します。本番データベースの新しいバックアップを取り、同じコマンドを本番環境に対して一度だけ実行します。
間違いから回復する
- フィールドを誤って削除した。 列とそのデータは、稼働中のデータベースから失われています。D1 の Time Travel による特定時点のバックアップから復元するか、フィールドを追加し直して、以前のオフサイト D1 ダンプから値を復元してください。
- 新しい環境が誤ったモデルでブートストラップされた。 埋め込まれたシードが古いか、存在しませんでした。
.emdash/seed.jsonを更新し(シードファイルを同期するを参照)、再ビルドして、空のデータベースを指してデプロイし、再度ブートストラップします。 - スキーマとテンプレートが一致しない。 デプロイとスキーマ変更は互いに独立しているため、意図的に順序を決めてください。追加的なスキーマ変更(新しいコレクション、新しい任意フィールド)を先に行い、そのあとでそれらを使うコードを展開します。削除の場合は、そのフィールドを使わなくなったコードを先にデプロイし、それからフィールドを削除します。