Metabase Transforms 完全指南:在数据库内持久化 ETL 结果并复用于查询
2026/9/10 11:29:03 网站建设 项目流程

Metabase Transforms 完全指南:在数据库内持久化 ETL 结果并复用于查询

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

Transforms(转换)是 Metabase Data Studio 中承担 "ETL" 的 "T" 的核心机制:你可以用 SQL、查询构建器或 Python 编写查询,Metabase 会执行它、在你的目标数据库中创建一张持久化表,并把这张表同步回 Metabase,使其能够作为问题(Questions)或其他 Transforms 的数据源。读完本文,你将掌握 Transforms 的启用方式、创建与调度流程、增量同步与 merge key 机制、依赖管理、版本化同步,以及其背后的应用数据库模型与驱动能力声明等源码级实现细节。

一、Transforms 是什么:概念模型

Transforms 用于对你的数据做预处理、清洗、表连接(join)、指标预计算等工作。其工作流程如下:

  • Transforms是查询(用 SQL 或查询构建器创建)或 Python 脚本,它们写回你的数据库并创建一张新的持久化表。适合用于清洗、连接、预聚合数据。
  • Transforms 通过tags(标签)jobs(作业)进行调度与组织:
    • 给 Transforms 分配标签(如 daily、hourly)来分组;
    • 一个 job 按调度(例如每天午夜)运行,并执行所有被分配了特定标签的 Transforms。
  • 每一次 Transforms 的执行都是一个run。run 会用最新结果替换目标表,你可以查看 run 历史来监控成功或失败。
  • 你可以inspect(检查)一个 Transform 来分析其数据流、join 行为与列分布(详见 Transform inspector)。

源码印证:从源码结构看,Transform 的完整数据模型定义在 src/metabase/transforms/schema.clj 中。其中::transform模式(第 104–124 行)声明了应用数据库中:transform表的每一列,包括:source(查询来源)、:target(目标表)、:last_checkpoint_value(增量检查点)、:target_table_id:table_dependencies(表依赖)等字段——文档中提到的 run、检查点、依赖等概念都能在数据库模型中一一对应。同样地,::transform-run(第 262–282 行)、::transform-job(第 185–197 行)、::transform-tag(第 317–325 行)等模式分别对应 run 记录、调度作业与标签的持久化结构。

二、支持 Transforms 的数据库

当前 Metabase 可以在以下数据库上创建 Transforms:

  • BigQuery
  • ClickHouse(仅 ClickHouse Cloud)
  • MySQL/MariaDB
  • PostgreSQL
  • Redshift
  • Snowflake
  • SQL Server

启用 Database routing(数据库路由) 的数据库,以及 Metabase 示例数据库(Sample Database),不能创建 Transforms。

由于 Transforms 会在你的数据库中创建表,连接所用的数据库用户必须具有相应权限。参见 Database users, roles, and privileges。建议为数据库配置 Writable connection(可写连接)。

源码印证:每个驱动通过 features 映射声明自己是否支持 transforms。例如 PostgreSQL 驱动在 src/metabase/driver/postgres.clj 中声明了:transforms/index-ddl:transforms/python:transforms/table三个能力位;MySQL 驱动在 src/metabase/driver/mysql.clj 声明了:transforms/table;而社区驱动模块(modules/drivers)中的 BigQuery、ClickHouse、Redshift、Snowflake、SQL Server 驱动(如 modules/drivers/snowflake/src/metabase/driver/snowflake.clj、modules/drivers/clickhouse/src/metabase/driver/clickhouse.clj)同样声明了:transforms/table能力,与文档列出的七种支持数据库完全一致。

三、Transforms 的两种类型

Metabase 支持两种类型的 Transforms:

  • 基于查询的 Transforms(query-based):用 SQL 或 Metabase 查询构建器编写,运行在你的数据库中。工作原理详见 How query-based transforms work。
  • Python Transforms:用 Python 编写,运行在专用的执行环境中。工作原理详见 How Python transforms work。

源码印证:src/metabase/transforms/feature_gating.clj 中的enabled-source-types函数揭示了三种来源类型的开关逻辑:当查询 Transforms 功能启用时返回"native""mbql"(分别对应 SQL 与查询构建器),当 Python Transforms 功能启用时追加"python"。在数据模型层,schema.clj 中的::transform-source模式按:type字段多态分发为:query(携带:query与可选的:source-incremental-strategy)和:python(携带:source-database:source-tables:body脚本体)两个分支。

这些功能开关由高级特性(premium features)控制。在 src/metabase/premium_features/token_check.clj 中:

  • query-transforms-enabled?要求实例具备:transforms-basic特性,且全局设置:transforms-enabled为 true;
  • python-transforms-enabled?额外要求:transforms-python特性;
  • any-transforms-enabled?则是两者的"或"。

这与后文"自托管部署"章节中 Basic / Advanced 两个档位的划分相互印证。

四、Transforms 的权限模型

Transforms 的权限配置取决于你的订阅计划:

  • Metabase Open Source / Starter:只有管理员(Admin)能看到并运行 Transforms。
  • Metabase Pro / Enterprise提供额外的权限控制:一个供非管理员访问 Transforms 的特殊 Data Analysts(数据分析师) 组,以及针对每个数据库的细粒度 Transform 权限:
    • 看到实例上的 Transforms 列表,用户必须能访问 Data Studio,即须为 Admin 或特殊 Data Analyst 组 的成员;
    • 执行某数据库上的 Transforms,用户须为 Admin 或 Data Analyst 组成员,并且还要拥有该数据库的 Transform permissions(转换权限)。

五、在自托管 Metabase 上配置 Transforms

如果你自行部署 Metabase,让 Transforms 跑起来的路径如下:

  1. 确认你的计划。Basic transforms(基于查询的)包含在自托管 Metabase 中;Advanced transforms —— Python Transforms、transform inspector 与 writable connections —— 需要自托管 Pro 或 Enterprise 计划并附带 Advanced transforms 附加组件。
  2. 连接一个可写的数据库。Transforms 会在数据库中创建和替换表,因此数据库用户需要 create、drop 与写权限(参见 Database users, roles, and privileges)。为了更干净的隔离,建议把 Transform 指向一个 writable connection。注意只有部分数据库 支持 transforms。
  3. Python Transforms 需要配置 runner。查询类 Transforms 不需要额外组件——它们直接在数据库内运行。Python Transforms 运行在独立的执行环境中,你需要把 Metabase 指向一个由 S3 兼容存储(AWS S3、MinIO 等)支撑的 自托管 Python runner。
  4. 在 Data Studio 中启用 Transforms。
  5. 创建并运行一个 Transform。创建基于查询的 Transform 或 Python Transform,手动运行一次,在Runs下检查结果。跑通之后,再用 jobs 进行调度。

六、Transforms 与 Models 的区别

Transforms 与开启了 model persistence(模型持久化)的 models 类似,但有关键差异:

  • Transforms 只能由拥有 transform 权限的分析师创建;而 models 可以由任何有权限在该数据源上创建查询的人创建(但只有管理员能在实例上启用 model persistence)。
  • Transforms 可以自选目标 schema 与表;model persistence 会自建 schema 与表。
  • Transforms 支持的数据库比 model persistence 更多。
  • Transforms 支持用 Python 创建。

实践建议:用 models 让非管理员在 Metabase 内创建自己的数据集并添加字段描述、语义类型等上下文;用 transforms 在数据库中创建持久化数据集并跨 Metabase 复用。文档同时指出,在 Metabase 未来版本中,model persistence 将逐步被 transforms 取代。在 Pro/Enterprise 计划上,还可以批量将 models 转换为 transforms,见 Convert models to transforms。

七、启用 Transforms

在开始编写 Transforms 之前,需要先在实例中启用 Transforms。

如果你使用的是 Metabase Cloud 计划,只有以 Metabase Store 管理员邮箱登录的人(而不仅仅是 Metabase 实例管理员)才能启用 basic transforms,因为在 Metabase Cloud 上 Transforms 按运行次数计费。

启用步骤:

  1. 点击 Metabase 右上角的grid 图标,选择Data Studio进入 Data Studio。
  2. 在 Data Studio 中,点击右侧边栏的Transforms
  3. 如果实例尚未启用 Transforms,会看到启用提示,直接点击启用即可。

启用 Transforms 之后,即可配置权限并开始创建 Transforms。

八、查看所有 Transforms

路径:Data Studio > Transforms(权限要求见权限模型)。

  1. 点击右上角grid 图标,进入Data Studio
  2. 在左侧边栏选择Transforms,即可看到实例上的全部 Transforms。

九、创建一个 Transform

路径:Data Studio > Transforms。

如果你使用 remote sync 且实例处于 "read-only"(只读)同步模式,将无法创建 Transforms。

创建步骤:

  1. 启用 Transforms。

  2. 点击右上角grid 图标,进入Data Studio

  3. 在左侧边栏选择Transforms

  4. 点击+ New并为 Transform 选择来源。

    你可以用 Metabase 的图形查询构建器、SQL 或 Python 来编写。查询类细节见 query-based transforms,Python 类见 Python transforms。

    如果选择Copy of a saved question(已保存问题的副本)作为来源,可以把一个现有 Metabase 问题(SQL 问题或查询构建器问题)的查询复制进 Transform。Metabase 只会_复制_该问题的查询,之后对原问题的修改不会影响 Transform 的查询。

  5. 编写 Transform 的查询或脚本。编写时可以引用其他 Transform 的目标表。

    • 如果写的是 SQL Transform,变量_必须_包裹在可选块([[ ]])中,或给定默认值,详见 variables in SQL transforms。
    • 如果 Metabot 已启用,可以用 Metabot 生成代码。
  6. 点击右上角Save,填写 Transform 信息:

    • Name(名称,必填):Transform 的名称。
    • Schema(模式,必填):目标 schema。它可以与源表的 schema 不同;在此输入框中键入新名称即可创建新 schema。注意 Transform 只能在_同一个数据库内_进行,不能从一个数据库写到另一个。
    • Table name(表名,必填):目标表名。Metabase 会把 Transform 结果写入该表,随后同步该表到 Metabase。
    • Folder(文件夹,可选):Transform 所在的文件夹,点击字段可选择或新建。
    • Incremental transformation(增量转换,可选):参见 Incremental query-based transforms 或 Incremental Python transforms。

  7. 保存后,可选地为 Transform 分配标签。标签用于让 jobs 按调度运行 Transforms。

源码印证:保存表单中的 Schema / Table name 对应数据模型 schema.clj 中的::transform-target模式:完整重写目标使用table类型({:type "table" :schema ... :name ...}),增量目标则使用table-incremental类型并额外携带:target-incremental-strategyappendmerge两种策略),这与前端设置表单中"增量转换"选项一一对应。执行入口在 src/metabase/transforms/execute.clj:execute!先通过resolve-target解析目标(包括挂接声明的索引,并一次性决定本次是否为"全量增量运行"),随后委托给transforms.i/execute!:query方法(由metabase.transforms.query-impl命名空间提供实现)完成"执行查询 + 同步目标表"。

十、使用 Metabot 为 Transforms 生成代码

Transform 的代码生成需要 AI features(AI 功能)。

可以让 Metabot 生成新的 SQL 或 Python Transform,也可以编辑现有 Transform:

  1. 进入Data Studio > Transforms;如果让 Metabot 编辑现有 Transform,先导航到该 Transform。

  2. 在 Transforms 视图中点击右上角的 Metabot 图标。

  3. 描述你想要 Metabot 编写的 Transform。可以指明想要哪种类型(Python 或 SQL),并通过 @-mention 指定数据源来帮助 Metabot 理解需求。

  4. Metabot 会为自己创建一份待办清单(展示其思考过程),然后逐条处理。

  5. 如果要求 Metabot 创建新 Transform,在聊天窗口中审查它给出的代码,然后点击代码片段下方的 "Create"。

之后可以继续与 Metabot 协作打磨代码:Metabot 会建议代码修改,并给出接受或拒绝修改的选项。

十一、编辑一个 Transform

路径:Data Studio > Transforms。

可以编辑 Transform 的名称与描述、查询/脚本、目标表与增量设置。即使 Transform 已经运行过或已被调度,也依然可以编辑。使用 remote sync 且实例处于 "read-only" 同步模式时无法编辑。

编辑查询或脚本

路径:Data Studio > Transforms > Definition(权限要求见权限模型)。

  1. 进入Data Studio > Transforms
  2. 找到要编辑的 Transform,点击 Transform 定义上方的Edit definition
  3. 编辑查询或脚本(可借助 Metabot)。

修改查询或脚本后,下一次运行(手动或调度)将使用更新后的查询并把结果写入目标表。如果表结构(列)发生了变化,且已有问题在查询这张表,那些问题可能会损坏。例如:新的 Transform 查询不再包含某个下游问题依赖的列,该问题就会损坏。

修改目标表

路径:Data Studio > Transforms > Settings。

在 Transform 的Settings标签页点击Change target即可更换目标表,需要选择保留还是删除旧目标表。删除不可撤销。

**建立在旧目标上的问题_不会_迁移到新目标表。**如果删除旧目标表,所有使用旧目标表的问题都会损坏;如果保留旧目标表,基于它的问题不会损坏,但也不会使用新目标表,从而变得过期。

十二、运行一个 Transform

Transform 可以手动运行,也可以用标签与作业调度:

  • 手动运行:进入Data Studio > Transforms > Runs(Transform 页面),点击Run
  • 调度运行:给 Transform 分配一个或多个标签,然后创建挑选这些标签的调度作业(scheduled job)。

首次运行会创建并同步该 Transform 生成的表,之后就可以编辑该表的元数据与权限。后续运行会删除并重建该表——除非使用增量 Transforms。

你可以在 Transform 页面或 Runs 视图中查看最近一次运行的时间与状态,运行时间以系统时区显示。Python Transforms 还可以看到执行日志。

源码印证:每次运行对应的TransformRun记录包含run_method(手动/调度)、statusstart_time/end_timemessageuser_id,以及增量运行专用的checkpoint_filter_field_idcheckpoint_lo_valuecheckpoint_hi_value字段(见 schema.clj)。对于增量 Transform,"上次处理到的检查点值"正是以字符串形式持久化在 Transform 的last_checkpoint_value列中,与下文"重新处理全部数据"的语义相符。

十三、检查(Inspect)一个 Transform

路径:Data Studio > Transforms > [Transform 名称] > Inspect。

Transform inspector 需要 Advanced transforms 附加组件。

Transform inspector 让你深入探查 Transform 的输入与输出。

十四、Transform 依赖关系

路径:Data Studio > Transforms > Dependencies。

Transform 查询可以使用其他 Transform 的数据,查询类 Transform 还可以引用 Metabase 的 questions 与 models。例如:一个 Transform 读取raw_events表并写入stg_events表,另一个 Transform 读取stg_events并写入events表。

Metabase 会跟踪 Transform 依赖,并按合理顺序执行:例如 Transform B 依赖 Transform A 创建的表,则 Metabase 先运行 A 再运行 B。

在 Pro 或 Enterprise 计划上,可以通过Data Studio > TransformsDependencies标签页查看依赖关系图。如果某个作业包含依赖了其他 Transform 产物的 Transform,则该作业会运行所有带标签的 Transforms,外加所有尚未处于最新状态的依赖项。

源码印证:依赖解析逻辑位于 src/metabase/transforms/dag.clj 与 src/metabase/transforms/coordinated_run.clj;数据模型中 Transform 的table_dependencies列(schema.clj)持久化了每张被引用的源表,而TransformDagRun记录(schema.clj)则以"以某个 Transform 为源、向上/向下展开"的方向(:direction)记录依赖子图的协调运行状态。从源码结构看,"作业连同其未更新依赖一起运行"正是由这些 DAG 协调运行机制实现的。

十五、增量 Transforms

路径:Data Studio > Transforms > Settings。

增量 Transform 只处理自上次运行以来新增的数据。例如:每天有新交易数据流入,Transform 每晚运行;每次运行只处理前一天运行之后新增的行。

默认情况下,Metabase 把这些行**追加(append)**到目标表。如果源表会随时间记录同一记录的变更,可以通过设置 merge key(合并键) 使 Metabase 更新现有行而非添加重复行。此时,checkpoint(检查点)字段决定哪些行算"新",merge key 决定 Metabase 是追加这些行还是更新匹配行。

前置条件

  • 数据中必须有一列可供 Metabase 检查新值以判定哪些数据是新的,称为Checkpoint(检查点)列
  • 检查点列的值必须递增,如自增 ID 或时间戳列。Metabase 通过查找_大于_已写入检查点值的值来判断"新"数据。
  • Schema 必须稳定,即表结构在各次运行之间不会变化。

源码印证:在 schema.clj 中,::checkpoint-strategy声明了检查点策略:{:type "checkpoint" :checkpoint-filter-field-id ...},并支持一个可选的:lookback(回看窗口)配置——"每次运行重读检查点之前valueunit时间跨度内的源行,从而迟到但早于水位线的行仍能被捕获",且仅支持时间型检查点列。这为文档所述"大于已写入检查点值"的语义提供了一个补充能力:处理迟到数据。

十五点一 添加 merge key 以 upsert 行

默认情况下,Metabase 输出 Transform 时是追加行。添加 merge key 后可以改为 upsert(更新或追加)。

为什么需要 merge key:有些源表在记录每次变更时都会产生新行。例如同一订单先以created出现一次、再以paid出现一次、再以shipped出现一次。如果追加这些行,同一订单就有三行——也许这正是你想要的。但如果你想就地更新这些记录,可以选一列(如订单 ID 列)作为 merge key。设置了 merge key 后,Metabase 会先尝试更新匹配键的现有记录;找不到匹配时再追加新记录。

添加 merge key:

  1. 进入Data Studio > Transforms中的 Transform 页面。
  2. 切换到Settings标签页,打开Only process new data(只处理新数据)
  3. Merge key中选择标识记录的列。如果目标表已存在,可以从列列表中选择;如果 Transform 尚未运行过、表还不存在,则需要键入每个列名并按逗号或回车。此时键入的应是数据库中的列名(可能与列表里显示的显示名不同)。

merge key 指向的是_目标_表(Transform 输出的列)中的列,而不是_源_表中的列。如果标识一条记录需要多列组合(如idregion),就选择多个列作为 merge key。

merge key 需要一个每次写入都递增的检查点字段(如updated_at时间戳),否则 Transform 永远看不到变化。

源码印证:merge key 的数据结构定义在 schema.clj:::merge-key-column允许携带已解析的:field-id(目标列已知时),或在目标表尚不存在时退化为:name引用;::merge-config{:type "merge" :unique-key [...]},与::append-config{:type "append"})一起构成::target-incremental-strategy的两种分支。"目标表尚不存在时需手动键入列名"这一 UI 行为,正对应 schema 中:name:field-id二选一的降级设计。

十五点二 重新处理全部数据以重建目标表

增量 Transform 运行过后,其Settings标签页会显示Last processed [checkpoint field],后面跟着 Metabase 已写入的最高检查点值。该值就是 Metabase 断点续传的依据——每次运行只处理它之后的行。

要清除该值并重新处理所有行,点击Reprocess all data。下一次运行时将从零重建目标表,处理每一行而不仅是新增行。点击后不会立即开始运行;需要手动运行 Transform,或等待下一次调度运行。

修改检查点字段同样会重置存储的值,因此换用另一个字段做检查点后,Transform 的下一次运行也会从零重建。

源码印证:"Last processed checkpoint" 展示的就是 Transform 记录中的last_checkpoint_value列(schema.clj);"Reprocess all data" 与该列被清空后、下一次运行按全量处理的行为,与执行入口resolve-target中计算的:full-incremental-run?决策(execute.clj)相对应——该决策在运行开始时基于数据库状态一次性做出,并在整个运行期间保持稳定。

十五点三 让 Transform 变为增量

增量 Transform 在查询类与 Python 类上的工作方式不同,详见 incremental query transforms 与 incremental Python transforms。

十六、Transforms 的版本化(Remote Sync)

路径:Admin > General > Remote sync。

可以通过 Remote Sync 将 Transforms 检入 git。启用 Transform 同步后,Metabase 会把 Transforms 序列化为 YAML 文件并推送到你指定的 GitHub 仓库分支。

启用 git 同步:

  1. 点击右上角grid 图标进入Admin
  2. General标签页的左侧边栏选择Remote sync
  3. 按 Set up Remote Sync 的步骤操作,并打开 "Transforms" 同步开关。

注意:该设置只控制 Transforms 是否被检_入_ git 仓库,_不_影响实例在只读模式下的行为。如果实例处于只读模式,你将无法创建或编辑 Transforms。

十七、小结与延伸阅读

Transforms 把 Metabase 从一个纯粹的 BI 查询工具扩展为"在数据库内执行持久化 ETL"的完整数据工作流平台:

  • 执行面:SQL / 查询构建器在数据库内执行,Python 脚本在独立 runner 中执行,结果统一写回目标数据库并同步回 Metabase;
  • 调度面:tags + jobs 按调度批量触发,依赖 DAG 保证执行顺序,runs 提供可观测的历史与日志;
  • 增量面:checkpoint 决定"什么是新数据",merge key 决定"追加还是 upsert",last_checkpoint_value持久化断点,支持"重新处理全部数据"重建目标表;
  • 治理面:按数据库的细粒度 Transform 权限、Special Data Analyst 组,以及通过 Remote Sync 把 Transforms 序列化为 YAML 纳入 git 管理。

建议进一步阅读:

  • 基于查询的 Transforms
  • Python Transforms
  • Python runner 自托管
  • Jobs 与 Runs
  • Transform inspector
  • Basic 与 Advanced transforms 附加组件
  • Data Studio 总览
  • 核心实现:src/metabase/transforms、src/metabase/transforms_base、驱动能力声明 src/metabase/driver/postgres.clj 与 modules/drivers

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询