metabase-representation-format について
Metabase Representation Formatは、MetabaseのユーザーコンテンツをYAMLツリーで表すポータブル形式で、インスタンス間のコンテンツ管理や検証に適しています。配置と階層はエンティティのフィールドで決まり、仕様書とスキーマ検証コマンドも用意されています。
主な機能
- 01ユーザーコンテンツをYAMLファイルで表現
- 0214種類のエンティティを定義
- 03数値のデータベースIDを可読名とエンティティIDに置換
- 04エンティティのフィールドで配置と階層を指定
- 05仕様抽出とスキーマ検証のCLI
活用シーン
- 01Metabaseインスタンス間でコンテンツを移行
- 02カードやダッシュボードの定義をGitで管理
- 03コンテンツファイルの形式を検証
- 04コレクションや配下エンティティの配置を調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ metabase/ agent-skills --skill metabase-representation-formatインストール後、Claude Code で/metabase-representation-formatを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
Metabase の表現形式
Metabase では、ユーザーが作成したコンテンツを YAML ファイルのツリーとして表現します。各ファイルは 1 つのエンティティ(コレクション、カード、ダッシュボードなど)です。この形式は Metabase インスタンス間で移植可能です。数値のデータベース ID は、人が読み取れる名前とエンティティ ID に置き換えられます。
この形式は、@metabase/representations npm パッケージに含まれる仕様で定義されています(_仕様を読む_を参照)。同じパッケージには、YAML ファイルのツリーをこの形式に照らして検証する CLI(npx @metabase/representations validate-schema)も含まれています。
エンティティ
この形式では 14 種類のエンティティが定義されています。
| エンティティ | SerDes モデル | 説明 |
|---|---|---|
| Collection | Collection | コンテンツを整理するためのフォルダーのようなコンテナーです。parent_id によって階層化されます。名前空間は、null(メイン)、"snippets"、"transforms"、"data-actions"、"data-apps"です。 |
| Card | Card | 質問、モデル、またはメトリックです。MBQL またはネイティブの dataset_query を保持します。表示タイプは、table、bar、line、pie、scalar などです。カードタイプは、"question"、"model"、"metric"です。 |
| Dashboard | Dashboard | フィルターパラメーターと任意のタブを備えた、カードのグリッドレイアウト(24 列)です。カードの配置を指定する dashcards 配列と、フィルターコントロールを指定する parameters 配列を含みます。 |
| Document | Document | ProseMirror AST を使用するリッチテキストページです。cardEmbed ノードでカードを埋め込んだり、smartLink ノードでエンティティにリンクしたりできます。 |
| Segment | Segment | テーブルにスコープされた保存済みフィルター定義です。定義は、source-table と filters のみを含む単一ステージの pMBQL クエリです。 |
| Measure | Measure | テーブルにスコープされた保存済み集計定義です。定義は、source-table と集計を 1 つだけ含む単一ステージの pMBQL クエリです。 |
| Snippet | NativeQuerySnippet | ネイティブクエリ内で {{snippet: Name}} を使って参照する、再利用可能な SQL 断片です。 |
| Transform | Transform | クエリまたは Python スクリプトの結果をデータベーステーブルに実体化します。ソースは MBQL/ネイティブクエリ、または Python スクリプトのいずれかです。 |
| TransformTag | TransformTag | トランスフォームを分類するラベルです。組み込みタイプは "hourly"、"daily"、"weekly"、"monthly"です。カスタムの場合は null です。 |
| TransformJob | TransformJob | 特定のタグに一致するトランスフォームを実行する、スケジュール設定されたジョブ(cron)です。 |
| TransformTest | TransformTest | テスト用の inputs を使ってトランスフォームを実行し、出力を expectations と照合します。トランスフォームの隣に保存されます。collections/transforms/{transform_slug}/{test_slug}.yaml |
| PythonLibrary | PythonLibrary | Python ベースのトランスフォームで利用できる、共有 Python ソースファイルです。 |
| Action | Action | データベースに書き込みます。type は "query"(パラメーター化されたネイティブ SQL)または "implicit"(implicit エントリーが指定するテーブルの 1 行)です。model_id は非推奨です。model_id がない場合、data-actions 名前空間のルートまたはデータアクションコレクション、あるいは collection_id で指定されたデータアプリのコレクションに配置されます。データアプリが実行するのは、そのデータアプリに属するアクションのみです。ネストされた query 配列と implicit 配列のうち、type が指定する定義を含むのは一方のみで、もう一方は [] です。 |
| Data App | DataApp | Metabase 内で実行されるカスタム React アプリです。data_apps/<slug>/ にあり、serdes/meta が [{model: DataApp}] で、slug がディレクトリ名と一致する data_app.yaml マニフェスト、その隣にあるビルド済みバンドル、およびアプリが実行する Cards と Actions を格納する collections/data_apps/ 配下の data-apps 名前空間のルート Collection で構成されます。 |
所有権と階層
重要 — フォルダー構成は見た目だけです。 Metabase 内でエンティティが配置される場所は、YAML ファイルがツリーのどこにあるかではなく、すべてそのフィールドによって決まります。フィールドを更新せずにファイルを移動しても、何も変わりません。ファイルを移動せずにフィールドを更新しても、正しく機能します。以下のフィールドを常に信頼できる情報源として扱ってください。
配置を実際に決定するフィールドは次のとおりです。
collection_id(コレクションの entity_id)— エンティティをそのコレクションに配置します。nullまたは省略した場合 → ルートコレクションです。- コレクションの
parent_id— コレクション自身の親を設定するのは、これだけです。 インポート時には、フォルダーツリー内のコレクションの位置は無視されます。parent_idがない場合(またはparent_id: nullの場合)、フォルダーがどれだけ深くネストされていても、コレクションはルートレベルのコレクションになります。あるコレクションを別のコレクションの下にネストするには、parent_idに親コレクションのentity_idを設定します。 - カードの
dashboard_id/document_id— カードをダッシュボードまたはドキュメントの下にネストします。このようなカードでは、親のcollection_idと一致するようにcollection_idも設定する必要があります。カードで両方を設定することはありません。
ディスク上では、ダッシュボードまたはドキュメントの下にネストされたカードは、親 YAML の隣にあるサブフォルダーに配置されます(例:my_dashboard.yaml の隣にある my_dashboard/card.yaml)。ただし、繰り返しになりますが、これは人が移動しやすくするためのものにすぎません。Metabase が読み取るのはフィールドです。
インポートパス
Metabase が YAML をインポートするのは、次のトップレベルディレクトリのみです。それ以外は無視されます。
collections/— すべてのユーザーコンテンツ(カード、ダッシュボード、ドキュメント、アクション、スニペット、変換など)。名前空間ごとにmain/、snippets/、transforms/、data_actions/、data_apps/に分割されています。databases/— 各テーブルの下にあるsegments/とmeasures/サブディレクトリ、および Library で公開された各テーブルのメタデータ。python_libraries/(python-libraries/も使用できます)。glossary/— 用語集の用語(仕様では対象外)。transforms/—transform_jobs/とtransform_tags/を含みます。actions/— アクションの従来の配置場所で、現在もインポート時に読み込まれます。新しいエクスポートでは、アクションはactions/サブディレクトリではなく、そのコレクションのディレクトリ内で、コレクションのカードの隣に書き出されます。data_apps/<slug>/— データアプリのdata_app.yamlとビルド済みバンドル。アプリのコレクションと、そのカードおよびアクションはcollections/data_apps/の下にあります。
serdes/meta
各エンティティには、model を示す単一のエントリを含むトップレベルの serdes/meta 配列があります。Metabase は、エンティティ自身のフィールド(entity_id、または Field の場合は name と table_id)から識別情報を導出します。古いエクスポートには、代わりに識別パス全体(エントリごとの {id, model, label?})が含まれていますが、Metabase は引き続きこれをインポートできます。例:
serdes/meta:
- model: Card
validate-schema は serdes/meta を読み取り、各ファイルがどのエンティティタイプを表すかを判断します。ネストされたエンティティや複合識別パスを含む詳細なルールは、仕様に記載されています。
仕様を読む
パッケージから現在の仕様を一時ファイルに抽出し、そこから読み込みます。
npx @metabase/representations@latest extract-spec --file "${TMPDIR:-/tmp}/metabase-representation-spec.md"
この SKILL で要約されているエンティティごとの構造に加えて、仕様では MBQL クエリの形式(ステージ、フィールド参照、結合、式、集計、フィルター/式演算子、時間単位のバケット化、ビニング)、ネイティブクエリとテンプレートタグ(text、number、date、boolean、dimension、temporal-unit、card、snippet、table)、可視化設定、クリック時の動作、ダッシュボード/カードのパラメーター、データアプリのレイアウト(data_apps/<slug>/data_app.yaml と collections/data_apps/ 内のアプリのコレクション)も扱っています。これらに関わる編集を行う場合は、仕様を参照してください。
必要なときに読み、先回りして読まないでください。 上記のエンティティのコンテンツファイルを読み込んだり変更したりする直前に限り、仕様を抽出して開いてください。たとえば、ユーザーがカードの編集、ダッシュカードの追加、トランスフォームの調整など、YAML の編集を伴う作業を依頼した場合です。セッション開始時や、表現形式の YAML に関係しない作業では抽出しないでください。セッションごとに一度だけ抽出してください。仕様は長いため、全体を読むのではなく、必要なセクションを検索してください。
検証
組み込みの CLI で編集内容を検証します。
npx @metabase/representations validate-schema --folder <path>
トップレベルのエクスポートフォルダー、または Git リポジトリのルートを渡してください。このツールは上記のインポートパスをたどり、各ファイルの serdes/meta を読み込んで適切な検証ルールを選び、失敗時にはゼロ以外の終了コードを返します。フィールドの構造を手作業で照合するより、こちらを使ってください。実行はほぼ瞬時なので、必要に応じていつでも実行してください。編集のたび、編集の合間、ファイルの構造に確信が持てないときなど、まとめて実行する必要はありません。
エンティティ ID の生成
すべてのエンティティには、entity_id に 21 文字の NanoID が必要です。バンドルされた CLI で 1 つ以上生成します。
npx @metabase/representations generate-entity-id
# → LZfXLFzPPR4NNrgjlWDxn
npx @metabase/representations generate-entity-id --count 5
UUID の生成
フォーマット内の一部のフィールドでは、NanoID ではなく v4 UUID が必要です。特に、MBQL 集計句の lib/uuid(order-by および後続のステージから参照されます)と、ダッシュボード/カードのパラメーターの id が該当します。次のコマンドで生成してください。
npx @metabase/representations generate-uuid
# → 1d4e9fdf-49ae-4fbe-ae27-05e7c6a5cfe8
npx @metabase/representations generate-uuid --count 3