用途
Metabase Representation Format 是 Metabase 的基于 YAML 的内容序列化格式。Metabase 将用户创建的内容表示为一棵 YAML 文件树,每个文件是一个实体(集合、卡片、仪表盘等)。该格式可在不同 Metabase 实例之间移植:数字数据库 ID 被替换为人类可读的名称和实体 ID。
该格式由与本文件一同提供的 spec.md 规范定义(上游来源:@metabase/representations npm 包)。同一 npm 包提供一个 CLI(npx @metabase/representations validate-schema),用于按该格式校验 YAML 文件树。
实体类型
该格式定义 13 种实体类型。
- Collection(集合):类似文件夹的内容组织容器。通过 parent_id 形成层级。命名空间:null(主)、"snippets"、"transforms"。
- Card(卡片):问题、模型或指标。持有 MBQL 或原生 dataset_query。显示类型:table、bar、line、pie、scalar 等。卡片类型:"question"、"model"、"metric"。
- Dashboard(仪表盘):卡片的网格布局(24 列),带筛选参数和可选标签页。包含用于卡片摆放的 dashcards 数组和用于筛选控件的 parameters 数组。
- Document(文档):使用 ProseMirror AST 的富文本页面。可通过 cardEmbed 节点嵌入卡片,并通过 smartLink 节点链接到实体。
- Segment(片段/筛选):作用域限定到某张表的已保存筛选定义。Definition 是一个 pMBQL 查询,仅含一个阶段,且该阶段只包含 source-table 和 filters。
- Measure(度量):作用域限定到某张表的已保存聚合定义。Definition 是一个 pMBQL 查询,仅含一个阶段,且该阶段只包含 source-table 和恰好一个 aggregation。
- Snippet(SQL 片段):可复用的 SQL 片段,在原生查询中通过 {{snippet: Name}} 引用(模型为 NativeQuerySnippet)。
- Transform(转换):将查询或 Python 脚本的结果物化为数据库表。来源为 MBQL/原生查询或 Python 脚本。
- TransformTag(转换标签):用于归类转换的标签。内置类型:"hourly"、"daily"、"weekly"、"monthly",或为自定义时取 null。
- TransformJob(转换作业):按 cron 调度执行匹配特定标签的转换的作业。
- PythonLibrary(Python 库):可供基于 Python 的转换使用的共享 Python 源文件。
- Action(操作):写入数据库。type 为 "query"(参数化原生 SQL)或 "implicit"(创建、更新或删除模型表的某一行;需要 model_id)。它像卡片一样通过 collection_id 存在于某个集合中。query 类型的操作可通过 model_id 归属于某个模型,也可不属于任何模型;数据应用只运行没有归属的 query 操作。嵌套的 query 与 implicit 数组中,恰好有一个持有其类型所对应的定义,另一个为 []。
- Data App(数据应用):在 Metabase 内运行的自定义 React 应用,位于 data_apps/<slug>/:一个 data_app.yaml 清单(含 serdes/meta [{model: DataApp, id: <entity_id>, label: <slug>}],且 slug 与目录名相同)、一个已构建的 bundle,以及一个 resources/ 目录,存放其拥有的 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 设为与父级的 collection_id 一致。一张卡片绝不同时设置两者。
在磁盘上,嵌套在仪表盘或文档下的卡片位于与父级 YAML 相邻的子文件夹中(例如 my_dashboard/card.yaml 与 my_dashboard.yaml 相邻)——但这同样纯粹是为了便于人类导航;Metabase 读取的是字段。
导入路径
Metabase 只从以下顶层目录导入 YAML,其他位置的任何内容都会被忽略:
- collections/——所有用户内容(卡片、仪表盘、文档、操作、片段、转换等),按命名空间分区:main/、snippets/、transforms/。
- databases/——仅导入每张表下的 segments/ 和 measures/ 子目录。
- python_libraries/(也接受 python-libraries/)。
- transforms/——包含 transform_jobs/ 和 transform_tags/。
- actions/——操作的历史位置,导入时仍会读取。新的导出会把操作写入其所属集合的目录下,位于 collections/main/ 中该集合的卡片旁边(不在 actions/ 子目录中;只有数据应用的 resources/ 才有该目录)。
- data_apps/<slug>/resources/——数据应用的资源:其集合(collection.yaml)、卡片(cards/)和操作(actions/)。当 Metabase 通过远程同步拉取仓库时,会连同应用的 data_app.yaml 一起加载。
serdes/meta
每个实体都带有一个顶层 serdes/meta 数组,编码其身份路径。每个条目为 {id, model, label?}——label 是名称的 slug 化形式,存在于以 NanoID 为键的实体上。示例:
serdes/meta:
- id: NDzkGoTCdRcaRyt7GOepg
label: my_entity_name
model: Card
validate-schema 读取 serdes/meta 来判断每个文件代表哪种实体类型。完整规则(包括嵌套实体和复合身份路径)在 spec.md 中。
阅读规范
本技能随附一份该规范的本地快照 spec.md,与 SKILL.md 放在一起。
除本 SKILL 中概述的各实体形态外,spec.md 还涵盖:MBQL 查询形式(阶段、字段引用、连接、表达式、聚合、筛选/表达式运算符、时间分桶、分箱)、原生查询与模板标签(text、number、date、boolean、dimension、temporal-unit、card、snippet、table)、可视化设置、点击行为、仪表盘/卡片参数,以及数据应用布局(data_app.yaml 与 resources/)。当编辑涉及上述任何内容时,请查阅 spec.md。
按需阅读,而非预先加载。仅当你即将读取或修改上述实体的内容文件时(例如用户要求编辑卡片、添加 dashcard、调整转换,或其它意味着要编辑 YAML 的工作)才打开 spec.md。不要在会话开始时,或与 representation YAML 无关的任务中打开它。
如果随附的副本看起来落后于上游包,该技能自身的 README.md 记录了如何用 extract-spec 刷新它。
校验
用内置 CLI 校验编辑:
npx @metabase/representations validate-schema --folder <path>
传入顶层导出文件夹,或 git 仓库根目录。该工具会遍历上面列出的导入路径,读取每个文件上的 serdes/meta 以选择正确的校验规则,失败时以非零码退出。优先运行它,而不是手动交叉核对字段形态。它基本上是瞬时的,因此在有用时随时调用——每次编辑后、编辑之间、任何时候对文件形态感到不确定。没有理由批量化。
生成实体 ID
每个实体都需要一个 21 字符的 NanoID 作为 entity_id。用内置 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