关于 metabase-representation-format
Metabase Representation Format 是一种以 YAML 树表示 Metabase 用户内容的可移植格式,适合需要在 Metabase 实例间管理或校验内容的团队。它以实体字段确定内容层级,并配有规范说明和模式验证命令。
主要功能
- 01以 YAML 文件表示用户内容
- 02覆盖 14 种实体类型
- 03用可读名称和实体 ID 替代数据库数字 ID
- 04通过实体字段定义归属与层级
- 05提供规范提取与模式验证 CLI
适用场景
- 01在 Metabase 实例间迁移内容
- 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 文件树。每个文件对应一个实体(集合、卡片、仪表板等)。此格式可在不同 Metabase 实例之间移植:数字数据库 ID 会替换为易读的名称和实体 ID。
此格式由 @metabase/representations npm 包附带的规范定义(参见 阅读规范)。该包还附带一个 CLI(npx @metabase/representations validate-schema),用于验证 YAML 文件树是否符合此格式。
实体
此格式定义了 14 种实体类型。
| 实体 | SerDes 模型 | 描述 |
|---|---|---|
| Collection | Collection | 类似文件夹的容器,用于整理内容。通过 parent_id 构建层级。命名空间:null(主命名空间)、"snippets"、"transforms"、"data-actions"、"data-apps"。 |
| Card | Card | 问题、模型或指标。包含 MBQL 或原生 dataset_query。显示类型:表格、柱状图、折线图、饼图、标量等。卡片类型:"question"、"model"、"metric"。 |
| Dashboard | Dashboard | 由卡片组成的网格布局(24 列),带有筛选参数和可选标签页。包含用于放置卡片的 dashcards 数组,以及用于筛选控件的 parameters 数组。 |
| Document | Document | 使用 ProseMirror AST 的富文本页面。可通过 cardEmbed 节点嵌入卡片,并通过 smartLink 节点链接到实体。 |
| Segment | Segment | 作用域限定于某个表的已保存筛选条件定义。定义是一个 pMBQL 查询,包含单个阶段,且仅含 source-table 和 filters。 |
| Measure | Measure | 作用域限定于某个表的已保存聚合定义。定义是一个 pMBQL 查询,包含单个阶段,且仅含 source-table 和一个 aggregation。 |
| Snippet | NativeQuerySnippet | 可在原生查询中通过 {{snippet: Name}} 引用的可复用 SQL 片段。 |
| Transform | Transform | 将查询或 Python 脚本的结果物化为数据库表。来源可以是 MBQL/原生查询,也可以是 Python 脚本。 |
| TransformTag | TransformTag | 用于分类 Transform 的标签。内置类型:"hourly"、"daily"、"weekly"、"monthly";自定义类型为 null。 |
| TransformJob | TransformJob | 定时任务(cron),用于执行与特定标签匹配的 Transform。 |
| TransformTest | TransformTest | 使用测试 inputs 运行 Transform,并根据 expectations 检查输出。与对应的 Transform 存放在一起:collections/transforms/{transform_slug}/{test_slug}.yaml。 |
| PythonLibrary | PythonLibrary | 供基于 Python 的 Transform 使用的共享 Python 源文件。 |
| Action | Action | 写入数据库。type 为 "query"(带参数的原生 SQL)或 "implicit"(写入其 implicit 条目所命名表中的一行);model_id 已弃用。若没有 model_id,则位于 data-actions 命名空间(其根目录或数据操作集合中),或位于由 collection_id 指定的数据应用集合中;数据应用只运行这些 Action。嵌套的 query 和 implicit 数组中,恰有一个包含其 type 指定的定义,另一个为 []。 |
| Data App | DataApp | 在 Metabase 内运行的自定义 React 应用,位于 data_apps/<slug>/:包含一个 data_app.yaml 清单(其 serdes/meta 为 [{model: DataApp}],且 slug 与目录名相同)、与清单并列存放的构建包,以及位于 collections/data_apps/ 下、属于 data-apps 命名空间的根 Collection;该 Collection 中存放应用运行所需的 Cards 和 Actions。 |
归属与层级
关键 — 文件夹布局仅供参考。 实体在 Metabase 中的位置完全由其字段决定,而不是由其 YAML 文件在目录树中的位置决定。移动文件而不更新字段不会有任何变化。更新字段而不移动文件仍然可以正常工作。请始终将以下字段视为唯一可信来源。
实际决定位置的字段:
collection_id(集合的 entity_id)— 将实体放入该集合。设为null或省略 → 根集合。- 集合上的
parent_id— 只有这个字段会设置集合自身的父级。 导入时会忽略集合在文件夹树中的位置;若没有parent_id(或parent_id: null),集合就会成为根级集合,无论其文件夹嵌套得多深。要将一个集合嵌套在另一个集合下,请将parent_id设为父集合的entity_id。 - 卡片上的
dashboard_id/document_id— 将卡片嵌套在仪表板或文档下。这类卡片还必须将collection_id设为与父级相同的值。一张卡片不能同时设置这两个字段。
在磁盘上,嵌套在仪表板或文档下的卡片位于父级 YAML 旁边的子文件夹中(例如,my_dashboard/card.yaml 与 my_dashboard.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
每个实体都带有一个顶层 serdes/meta 数组,其中有一个条目,用于标明其 model;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"
除了本技能中概述的各实体结构外,规范还涵盖: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 生成一个或多个:
npx @metabase/representations generate-entity-id
# → LZfXLFzPPR4NNrgjlWDxn
npx @metabase/representations generate-entity-id --count 5
生成 UUID
格式中的某些字段要求使用 v4 UUID,而不是 NanoID——尤其是 MBQL 聚合子句中的 lib/uuid(由 order-by 和后续阶段引用),以及仪表板/卡片参数中的 id。使用以下命令生成:
npx @metabase/representations generate-uuid
# → 1d4e9fdf-49ae-4fbe-ae27-05e7c6a5cfe8
npx @metabase/representations generate-uuid --count 3