如何将 dbt ETL 管道迁移到 Databricks
DataHot 速览
Databricks 官方博客介绍将现有 dbt 转换项目重新指向 Databricks Lakehouse 的迁移方法。文章称只需更换 dbt-databricks 适配器与连接配置、处理少量 SQL 方言差异,无需重写 DAG 或业务逻辑。Databricks 提供 Delta Lake、Apache Iceberg、Unity Catalog 与 Lakeflow Jobs 等能力,并称已有超过 3,000 家组织在 Databricks 上运行 dbt。作者建议从转换层开始增量迁移,以便逐模型验证输出、降低风险并更快看到成本收益。
为什么值得关注:对正在评估数仓/湖仓迁移或 dbt 落地 Databricks 的数据团队,这篇官方实践给出了从适配器切换、SQL 方言到治理与成本收益的迁移思路。
本文目录 14 节
译文
AI 逐段翻译越来越多的团队正在Databricks Lakehouse上运行他们的 dbt 转换:这是一个开放平台,无锁定、统一管道、内置 Unity Catalog 治理,并具有出色的性价比。
你的 dbt 项目可以正常工作:模型能编译,测试能通过,你的转换逻辑存在于受版本控制的 SQL 和 YAML 中,而不是硬编码到某一个数据仓库中。dbt 的开放适配器框架正是为这种解耦而设计的,因此从一个云数据仓库迁移到另一个,主要只需更改适配器和连接配置,再加上一些方言调整——而无需重写你的 DAG 或业务逻辑。
Databricks 通过协同设计的dbt-databricks 适配器、开放湖仓存储(Delta Lake和Apache Iceberg™)、Unity Catalog以及Lakeflow Jobs实现了这一点,为你提供一个开放、统一的平台,让 dbt 从第一天起就能在内置治理和出色性价比下运行,使其成为运行你的 dbt 工作负载的理想之地。这就是为什么已有超过 3,000 家组织在 Databricks 上运行 dbt。
如果你一直在评估迁移,好消息是你无需重建项目。本文将介绍如何通过替换适配器和配置文件,将可正常工作的 dbt 项目重新指向 Databricks,处理少量 SQL 差异,并将转换逻辑保留在 dbt 中。
为什么重新指向 dbt 是迁移的有力起点
数据仓库迁移项目反复出现的挑战是试图一次性迁移所有内容,这可能导致延迟和瓶颈。更好的方法是从转换层开始,这是快速从迁移中释放成本节省的途径。
dbt 项目本身已是模块化且可测试的。这使其成为增量迁移的理想候选。当你将 dbt 重新指向 Databricks 时,你将获得:
- 即时验证。你可以逐个模型地比较旧仓库和新仓库之间的输出
- 降低风险。你的转换逻辑不变,因此你将变量隔离在计算和存储上
- 一个可用的概念验证。在迁移数据摄取或 BI 层之前,利益相关者就可以看到查询在 Databricks 上运行
- 更快实现价值。与其一次性迁移整个技术栈,不如先迁移转换层

前提条件
范围:本指南仅涵盖重新指向你的 dbt 转换层。它假设你的源数据已经在 Databricks 中——以 Delta 或 Iceberg 表的形式落地并注册在 Unity Catalog 中——并且你的目录和架构已存在。迁移数据本身和设置 Unity Catalog 是单独的工作;请参阅 Databricks 迁移指南和 Lakebridge 了解这些内容。
开始之前,请确保你拥有:
- 一个已预置 SQL 仓库的 Databricks 工作区
- 已创建目标目录和架构的 Unity Catalog 设置,并且你的源(原始/青铜)表已作为 Delta 或 Iceberg 落地并注册在 UC 中
- 你现有的 dbt 项目在版本控制中(dbt Core 1.8+ 或 dbt Platform)
- 本地安装了 Python 3.9+(适用于 dbt Core 用户)
- 访问凭证:Databricks 个人访问令牌或 OAuth 配置
- 可选地,Lakebridge可以自动化大部分 SQL 转换。它会扫描你的源仓库和 dbt 模型中的 SQL,将方言特定的 SQL 转换为 Databricks Lakehouse,并将结果与源进行核对。它重新指向 dbt 项目中的 SQL,而不是迁移 dbt 本身,并且不会迁移使用单独模式的数据(Lakehouse Federation + CTAS、COPY INTO 或 Auto Loader)。
本示例中我们将要迁移的模型是一个标准分析事实表,构建在两个源模型之上:orders和order_items。它聚合订单级数据以计算总收入,并为过去一年的每笔单独交易编制所售产品列表。
此模型使用了若干常见的SQL 方言模式,例如regexp_substr、div0和object_construct,这些在不同数据仓库之间往往有所不同,使其成为一个很好的例子。一旦你了解如何处理这些模式,你就可以将相同的方法应用到项目中的每个其他模型。
第 1 步:安装适配器并添加 Databricks 目标
这部分涵盖一次性迁移工作,包括安装适配器、映射命名空间以及处理方言差异。
安装 dbt-databricks 适配器
这dbt-databricks适配器是 dbt 项目与 Databricks Lakehouse 仓库之间的桥梁。它将 dbt 编译的 SQL 转换为 Databricks 兼容的查询。
(dbt Platform 用户:在新环境中将连接类型选择为“Databricks”,详见dbt 文档 - 适配器会自动安装。)
在 `profiles.yml` 中添加 Databricks 目标。保留你现有的目标不变;验证期间你会需要它。在它旁边添加第二个目标:
验证连接:
你应该会看到:Connection test: [OK connection ok]。
如果你仍然无法连接,请遵循Databricks + dbt 集成指南和dbt Databricks 配置文件参考中的连接故障排除步骤。
专业提示: http_path决定查询是在 SQL 仓库(推荐用于 dbt)上运行还是在通用集群上运行。SQL 仓库为 SQL 密集型工作负载提供更好的性价比。
第 2 步:将表源指向 Unity Catalog 并添加测试
Databricks 使用三级命名空间:catalog.schema.table。更新sources.yml中fct_orders读取的条目:
更新schema.yml以包含测试
专业提示:如果你跳过database:,查询会落到工作区的默认目录。请显式设置它。
第 3 步:首次编译
现在为该模型运行 dbt compile:
我们的fct_orders模型产生了 3 个编译错误,详情如下,全部与方言相关。这是预期之内的,虽然这三个代表了大多数项目会遇到的方言问题,但它们并非全部:更大的迁移还会遇到增量模型策略、快照以及没有直接对应项的半结构化函数。
我们有意使用一个依赖方言特定模式的示例模型,例如带有位置参数的REGEXP_SUBSTR,DIV0 用于安全除法,以及 OBJECT_CONSTRUCT 用于构建 JSON——这些函数在不同数据仓库之间存在差异。这样,最初的 dbt run 错误就会成为转换过程的向导,向你展示如何将它们转换为可移植的宏和 Databricks 友好的 SQL,以便你可以在项目的其余部分应用相同的修复。为了演示,我们将逐一介绍每个错误、根本原因和修复方法。在深入探讨错误之前,先说明一下可移植性:如果某个函数有可移植的等效函数,dbt 的跨数据库宏(dbt.* 命名空间)可以让你编写一次,就能在任何数据仓库上编译——在你进行标准化时值得采用。我们将逐一介绍每个错误及其修复方法,然后展示如何在一个大型项目中自动化转换。
错误 1:REGEXP_SUBSTR 方言不兼容
Databricks 遵循 Apache SQL 方言,仅支持 2 个参数用于 REGEXP_SUBSTR
修复: 使用 Databricks 原生的 regexp_extract() 函数
你也可以让 Genie Code 为你完成此转换,修复这类方言差异正是它的专长。我们将手动手动完成全部三项,以便你看到正在发生变化的内容。
错误 2:DIV0(安全除法)
根本原因:某些数据仓库使用 DIV0 在除以零时返回 0 而不是抛出错误。
修复:将 dbt_utils 添加到你的包中,并使用其内置的 safe_divide 函数
错误 3:object_construct(JSON 构建器)
无法解析例程 `object_construct`
修复:使用 Databricks 的 named_struct 函数
重新运行编译:
编译成功。此模型的总方言更改: 已安装 dbt_utils 包(用于安全除法),regexp_substr 调用已转换为 regexp_extract,div0 调用已替换为 dbt_utils.safe_divide(), object_construct 调用已转换 为 named_struct。
手动修复三个函数很容易。一个真实的 dbt 项目有数百或数千个模型,而这些方言差异正是 AI 工具能够自动弥补的。Genie Code 会转换方言特定的 SQL,并直接在编辑器中处理这些修复,这样你就可以将时间花在审查转换上,而不是编写每一个转换。
步骤 4:首次运行
编译成功后,执行模型以及所有存在的测试:
模型构建和测试均通过。 专业提示:
- 运行时。 记下它——你将在下一步中与旧数据仓库进行比较。
- 数值列上的测试失败。 如果
相等性或accepted_values测试失败,这几乎总是浮点精度问题,而不是逻辑错误。
步骤 5:逐行对照旧数据仓库进行验证
一次成功的 dbt run 证明 SQL 可以执行。现在,我们需要在旧数据仓库和 Databricks 之间核对输出。使用 dbt-audit-helper 逐行比较。
安装:
比较 fct_orders 在两个数据仓库中的结果。 在 analyses/compare_fct_orders.sql 中:
针对 Databricks 运行它(假设你已将旧输出复制到 Databricks 中进行比较,或执行跨数据仓库比较):
预期结果:
注意: 这些示例涵盖了最常见的模式,但并非详尽无遗。对于任何其他不匹配(例如字符串修剪、排序规则或自定义 UDF 行为),设置 summarize=false 以物化样本行,检查 in_a 和 in_b 不同的几个主键,修复模型或宏,然后重新运行,直到获得 100% 匹配。
在我们的运行中:fct_orders 完全匹配。
步骤 6:在 Databricks 中部署
无需为 dbt 维护单独的编排层,你可以使用 Lakeflow Jobs 在一个管道中运行 dbt,同时运行上游摄取和下游操作。dbt 是 Jobs 中的 一等任务类型,你不需要外部编排器或自定义 Docker 镜像。
创建 Job:
- 工作区 → Jobs 与 Pipelines → 创建 Job
- 任务类型:dbt
- Git 源:你的 dbt 仓库
- 命令:
- SQL 仓库:你的生产仓库
- 仓库目录:表将写入的目录:dev
- 仓库模式:表将写入的模式:analytics
- 调度:你偏好的频率
Jobs 开箱即用提供的内容:
- 完全托管——无需购买、保护或维护额外基础设施
- 能够创建单一管道,将 dbt 任务与上游摄取管道以及下游任务(如 Power BI 刷新)一起运行

步骤 7:切换和停用
一旦你验证了 dbt 项目并在 Databricks 上部署,下一步就是以受控方式将生产流量迁移到 Databricks,保留一条简短的回滚路径,并避免不必要地长时间支付两个数据仓库的费用。
保留此检查清单:
- 翻转生产目标在
profiles.yml中,使prod指向 Databricks——所有新的生产运行现在都写入 Databricks。 - 更新 CI/CD 凭据,使 PR 检查针对 Databricks 暂存目录运行,而不是旧数据仓库。
- 通过
system.billing.usage监控成本,以确认 Databricks 支出情况。 - 一旦回滚窗口关闭且你确信 Databricks 在生产环境中稳定,就停用旧目标。
扩展到项目的其余部分
你刚刚完成的大部分工作都是一次性的:适配器安装、profiles.yml 目标以及源命名空间更改。一旦这些就位,重新指向下一个模型只需增量方言修复。
某些模式需要的不仅仅是方言替换,你在扩展时会遇到它们:
- 增量模型——增量策略因平台而异;你的源使用的策略可能无法 1:1 映射到 Databricks 增量策略,因此你需要重新选择策略并重新验证增量逻辑。
- 快照——你需要重新指向快照逻辑,并单独将现有的历史快照数据迁移过来,以免丢失历史记录。
- 半结构化和小众函数——某些源函数没有直接的 Databricks 等效函数,需要重写或使用宏,而不是一行代码。
对于这里的繁重工作,请依赖完整的迁移指南。
从那里开始,以小批次进行迁移,并按照 DAG 顺序操作——先处理源,然后是暂存、中间层和集市,这样每个批次都能干净地针对你已迁移的模型进行验证。并行运行两个目标,并使用审计助手比较每个模型,直到它们全部匹配。当最后一个模型变绿时,切换整个项目。本指南是重新指向的简化演练,迁移的完整范围涵盖在我们的 公开迁移指南。
结论
将 dbt 重新指向 Databricks 是一种实用、低风险的仓库迁移起点。你的模型和测试保持不变——你改变的是它们的运行位置,并且你获得了开源格式和标准,例如 Delta Lake 和 Apache Iceberg™,同时 Unity Catalog 在平台之上提供治理和血缘,该平台还可以服务于你的下游 AI 工作。从一个模型开始,比较输出,然后逐步扩展,直到你能够自如地让 Databricks 成为你 dbt 项目的主要归属地。
准备尝试了吗?
- 设置一个 Databricks 免费试用版
- 安装 dbt-databricks 适配器
- 针对 Databricks Lakehouse 仓库运行你的首个 dbt compile。之后,按照 Databricks 文档部署一个 Databricks 作业以在生产环境中执行 dbt 模型。
有关 dbt 与 Databricks 的更多信息,请探索 GitHub 上的 dbt-databricks 适配器。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏