mcpField
U
using-dbt-state

using-dbt-state

github.com/dbt-labs数据与数据库747560 次安装1 周前更新
代码仓库

关于 using-dbt-state

介绍 dbt State 的技能;该服务端机制会判断选中的 dbt 对象应复用还是重新构建。它帮助团队在开发、CI 和生产环境减少不必要的工作,并考虑 SQL 语义与数据新鲜度。

主要功能

  1. 01决定跳过、克隆或构建节点
  2. 02比较规范化后的 SQL 语义
  3. 03考虑上游数据新鲜度
  4. 04配置复用行为并诊断原因
  5. 05支持开发、CI 和生产环境

适用场景

  1. 01在多次运行间复用未变模型
  2. 02避免重建未受影响的下游节点
  3. 03调查节点复用或重建的原因

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dbt-labs/dbt-agent-skills --skill using-dbt-state

安装后在 Claude Code 中输入/using-dbt-state确认已加载。

详细介绍

使用 dbt State

dbt State 是一种由服务器支持的复用机制。不要将它与 dbt 的 state:modified 选择器或 --state 延迟构建混为一谈。

在构建每个选定节点之前,dbt 会询问 dbt State 服务器,该对象能否跳过(从目标架构复用)、克隆(从其他架构复用),还是必须构建。它是 State-Aware Orchestration 的后继方案,但可在 dbt Core、开发环境和 CI 中使用,而不只是用于生产环境中的 Fusion。

dbt State 是付费产品,但无需订阅 dbt platform(原名 dbt Cloud)。

常见误解

误解事实
“dbt State 就是 state:modified / --state”不是。 state:modified 会将文件内容与由你管理的清单进行哈希比较(并且必须确保清单是最新的,例如通过 dbt parse 或类似方式),然后重建 state:modified+(所有后代节点)。dbt State 会在服务器上自动管理状态,无需维护最新的对比清单;它会将 SQL 解析为语法树并比较语义哈希,考虑上游数据的新鲜度,并且仅在后代节点确实依赖该变更时才重建(而不是整个 + 子树)。
“它只能用于 Fusion / 生产环境”它可在 Core、dbt platform 和 Fusion 中使用,适用于开发、CI 和生产环境,并可与任何编排器搭配使用。
“dbt Core 用户无法使用它”可以使用。dbt Core 1.7–1.11 需要执行 pip install dbt-state。它已内置于 dbt Core 1.12 / v2.0 和 Fusion 中。
“它是免费的 / 它在本地运行”它会调用 dbt State 服务器,并且需要通过 dbt platform 账户或独立的 dbt State 账户进行身份验证(app.state.dbt.com)。复用量按 DATT 计量——每日活跃目标表(见下文“计费”)。
“它会把我的数据发送给 dbt Labs”它会发送最后修改时间戳和 SQL 文本。SQL 会先进行哈希处理,然后丢弃——哈希处理后,dbt Labs 无法读取查询内容,也永远无法访问原始数据。

复用决策的工作方式

对于每个选定节点,dbt State 会选择成本最低的有效方案:

  1. 跳过——对象存在于目标架构中,语义哈希未变化,并且没有父节点的数据比 lag_tolerance 更新。不会执行任何操作。
  2. 克隆——在其他架构(例如生产环境或队友的开发架构)中存在匹配对象(哈希相同且数据新鲜)。dbt State 会将其克隆,并标记为已复用。如果数据仓库支持,则使用零拷贝克隆;否则会运行 CTAS 语句,从其他位置复制转换后的数据。测试结果也会复用——即使未重新执行,失败的测试仍会显示。
  3. 构建——没有有效的复用方案。正常构建,并自动对未选中的上游节点启用延迟构建。

如果某个节点已被选中执行,但其输入在目标架构中不存在,dbt State 会像往常一样使用延迟构建。如果存在 manifest.json,则会使用该文件;否则会根据 generate_*_name 宏,尽力推测正确的 FQN(相关注意事项)。延迟构建不会消耗 DATT。自托管用户可在 profiles.yml 中使用 defer_to_target 配置指定要延迟构建到的架构。dbt platform 用户无需进行此配置。

为了获取数据新鲜度,dbt 会为每个输入关系读取数据仓库元数据(或 loaded_at_field / loaded_at_query)。对于未配置 loaded_at 的视图,dbt 会沿上游遍历,直到找到实际表。

查询规范化及模型为何重新构建

dbt State 会对解析后的语法树进行哈希处理,因此会忽略不影响结果的更改——空白字符、注释、表别名以及 dbt lint --fix 的格式化。只有在模型的逻辑或数据发生变化时,模型才会重新构建。

易变 SQL(current_timestamp()、getdate()、random()):默认视为逻辑——哈希使用函数名称,而非运行时值,因此每次运行都不会使模型失效(否则,getdate() 下游的所有内容都无法复用)。要让模型在值变化时重新构建:

  • 设置 evaluate_volatile_sql: true(首选——涵盖模型中的所有函数,并可像任何配置一样继承)。dbt State 会将函数值模拟进哈希。
  • 或使用等效的 Jinja 写法(例如 {{ run_started_at }})——Jinja 会在解析之前渲染,因此每次运行都会改变编译后的 SQL。

非确定性 Jinja(例如,dbt_utils.get_relations_by_pattern 返回的关系顺序不固定)会产生不同的编译哈希,并触发重新构建,即使逻辑并未改变。

配置更改:只有与构建相关的配置会影响哈希(materialized、on_schema_change、severity,等等)。外观类配置(meta、tags)会被忽略。如果 post-hook 会根据被忽略的字段修改表(例如,将 meta 应用为数据仓库标签),请设置 execute_hooks_on_any_reuse: true,以便复用时运行钩子。

配置速查

在 dbt_project.yml 的 models: +state: 下、schema.yml 的 config.state 中,或在 {{ config(state={...}) }} 中设置。

配置默认值用途
lag_tolerance45m数据可以过期多久,节点才符合重新构建条件。仅影响数据新鲜度——SQL 发生更改仍会触发重新构建。
require_fresh_data_fromany触发重新构建时,是否要求 any 或 all 直接父节点拥有新鲜数据。
evaluate_volatile_sqlfalse对易变函数的运行时值而非名称进行哈希处理。
pre_cloneif_missing运行前通过克隆生产环境来预填充增量模型/快照(never / if_missing / always)。
execute_hooks_on_any_reusefalse即使复用节点,也运行 pre-hook/post-hook。
defer_to_targetprod(仅限自行管理,配置文件)延迟到或从哪个配置文件目标进行克隆。
metadata_warehouse配置文件中的 warehouse(仅限 Snowflake,配置文件)用于元数据查询的独立数据仓库。

支持的数据仓库:Snowflake、Databricks、BigQuery、Redshift。

计费:每日活跃目标表(DATT)

dbt State 的使用量按 **DATT(每日活跃目标表)**计量,而不是按“构建的模型”计量。

  • 目标表是由项目管理的数据库对象(按数据库 + schema 区分):种子、快照、模型(包括增量模型),以及每个不同的测试——即使测试未存储在数据库中(store_failures 关闭)。示例:dim_customers 上针对 id 的 not_null 和 unique 测试 = 3 个目标表(模型 + 2 个测试)。
  • 当 dbt State 在某一天(UTC)对某个目标表至少执行一次跳过、克隆或测试复用时,该目标表就会成为一个 DATT。同一天内对同一目标表的所有复用只计为一个 DATT。完整构建不属于复用。
  • 视图永远不会作为 DATT 计费,即使视图被复用或克隆也一样。附加到视图的测试仍按正常方式计费。

如需了解定价详情,请引导用户访问 https://www.getdbt.com/product/dbt-state。

实现最佳效果的优化

  • 按环境设置 lag_tolerance — 在开发环境中将其设得较高(例如一周),这样当数据仅略有滞后时,dbt 就不会执行任何操作;克隆的成本很低,但不执行任何操作成本更低。示例:
    # dbt_project.yml
    models:
      +state:
        lag_tolerance: "{{ '4h' if target.name == 'prod' else '7d' }}"
    
  • 在开发过程中继续使用选择器。 dbt State 复用的任何目标表在当天都计为一个 DATT(即使它处于滞后容忍窗口内)。只选择你正在处理的节点,让普通的延迟处理其余部分——未改动且未选中的节点不会产生 dbt State 用量。
  • 在生产环境中减少复杂选择器的使用。 dbt State 会让大多数作业趋近于普通的 dbt build;让它决定要重建什么,而不是针对每个作业手动调整选择。指定 lag_tolerance 以避免过度构建。
  • 指定列而不是使用 select *,以提高复用的可能性。如果 dbt State 无法证明 table.* 或类似表达式的列集合相同,就会重建以确保正确。这对于视图尤其重要。目前不会使用 Fusion 的静态分析。

诊断令人困惑的行为

症状原因/修复方法
含有 current_timestamp() 的模型持续重建可能是某处设置了 evaluate_volatile_sql: true,或者 Jinja 值(例如 run_started_at)导致编译后的 SQL 发生变化。如果你希望复用,请将易变 SQL 保持为默认值(logic)。
模型在“没有变化”的情况下重建外观上的变化不是原因(这些变化已被规范化处理)。请检查非确定性的 Jinja(未排序的宏输出)、与构建相关的配置变更,或超过 lag_tolerance 的较新上游数据。元数据表可能会将表视为被插入命令修改,即使没有添加新行。可以考虑使用 loaded_at_field,但这可能会增加数据仓库中的成本——元数据查询通常免费,但 loaded_at_field 会执行标准的付费查询。
复用模型时未运行后置钩子默认情况下,复用时不会运行钩子——请设置 execute_hooks_on_any_reuse: true。
想知道节点为何被复用/重建使用 dbt-state explain 命令(dbt v1.7–1.12)检查决策。
需要身份验证/访问权限使用你的 dbt platform 账户或 standalone dbt State 账户登录。对于组织,请在 dbt_project.yml 的 dbt-cloud: 下设置 state-org-id。

v1(Python)与 v2(Rust/Fusion)

dbt Core 1.7–1.11dbt Core 1.12 / v2.0Fusion
安装需要 pip install dbt-state内置内置
  • dbt v1.7-1.11 用户必须安装独立的 dbt-state 软件包才能使用 dbt State。
  • dbt v1.12+ 用户会自动包含 dbt-state 软件包。
  • dbt v2.0+(Core 或 Fusion 发行版均可)内置了客户端逻辑的 Rust 实现,因此无需单独安装。

复用行为、配置和查询规范化都在服务端执行,在所有引擎中的行为一致。v1 的主要区别在于,1.7–1.11 需要单独安装 dbt-state。dbt v2 不提供 dbt-state explain 诊断功能。

相关文档

  • 概览:/docs/deploy/dbt-state-about
  • 设置:/docs/deploy/dbt-state-setup · 示例:/docs/deploy/dbt-state-examples
  • 监控活动:/docs/deploy/dbt-state-interface · 延迟:/docs/deploy/dbt-state-deferral · CI/CD:/docs/deploy/dbt-state-cicd
  • 配置:/reference/resource-configs/dbt-state-configs · lag_tolerance · defer_to_target

评论

支持 Markdown