<@U088WCP3B4P> 有时候会在本地进行一些dbt测试,如何把这些测试排除在收集数据到数据库...
# ask-elementary-ai
l
@kapa.ai 有时候会在本地进行一些dbt测试,如何把这些测试排除在收集数据到数据库之外
k
A message from kapa.ai
可以。有几种方式在本地开发/临时运行时避免把测试与元数据写入 Elementary 表: - 仅禁用 on-run-end 钩子(保留测试可用):在 dbt_project.yml 的 vars 中按环境关闭上传与结果收集
Copy code
yaml   vars:     disable_dbt_artifacts_autoupload: "{{ target.name != 'prod' }}"     disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}"     disable_run_results: "{{ target.name != 'prod' }}"     disable_tests_results: "{{ target.name != 'prod' }}"
这样本地或非 prod 运行不会把数据写入 Elementary,减少开销(会影响本地 edr report 的完整性)([Local 开发禁用钩子](https://slack.com/archives/C02CTC89LAX/p1708674780847219); [按环境禁用钩子](https://slack.com/archives/C02CTC89LAX/p1674814915518089))。 - 只在特定运行中禁用 Elementary 的 on-run-end:参考“Can I disable the on-run-end hooks”文档,按需跳过这些钩子以免把临时运行的数据收集进仓库(例如临时/adhoc 流程)([禁用 on-run-end 钩子](https://slack.com/archives/C02CTC89LAX/p1710871555212829))。 - 完全禁用 Elementary 包(不推荐长期使用):
Copy code
yaml   models:     elementary:       +enabled: "{{ (target.name == 'prod') | as_bool }}"
这样在非 prod 环境不构建/运行 Elementary 的模型与逻辑(会导致测试结果收集、告警等不可用)([按环境禁用包](https://slack.com/archives/C02CTC89LAX/p1674814915518089); [在 test/build 时禁用模型的做法与影响](https://slack.com/archives/C02CTC89LAX/p1691076162405429))。 - 仅过滤特定运行:通过 dbt 的选择器/标签,让日常正式流程纳入 Elementary,而本地/临时运行排除;或给正式模型/测试打标签并在 Elementary 报告中过滤展示(只显示“daily”标签等)(适合只想在报告里区分)([使用标签过滤](https://slack.com/archives/C02CTC89LAX/p1710871555212829))。 如果你的目标是“本地测试完全不写 Elementary 表”,首选做法是设置上述 vars 禁用 on-run-end 上传与结果收集。
l
@kapa.ai target.name取的是哪个值?
k
A message from kapa.ai
target.name 是 dbt 的内置上下文变量,表示当前运行所使用的 profiles.yml 中的目标环境名称(即 target)。常见做法是在 profiles.yml 定义多个 outputs(如 dev、staging、prod),再通过 target 选择其一;运行时 target.name 就等于所选的 output 名称(例如 "prod" 或 "dev")。你可以在 dbt 命令行用 --target 指定,或在 profiles.yml 的 target 字段默认指定。([FAQ: 禁用 hooks 示例里以 target.name 判断环境](https://docs.elementary-data.com/oss/general/faq);[Slack 讨论:将不同环境配置为不同 target 并用 --target 切换](https://slack.com/archives/C02CTC89LAX/p1664213730105049))
l
@kapa.ai +enabled: "{{ (target.name == 'prod') | as_bool }}"是什么意思
k
A message from kapa.ai
它是 dbt_project.yml 中对 Elementary 包的启用条件配置,含义是:只有当当前运行的 dbt 目标环境名 target.name 等于 'prod' 时,才启用 elementary 模型;否则(如本地/开发环境)不启用。也就是“仅在 prod 运行 Elementary”。示例被多次用于按环境禁用 Elementary 的推荐做法(避免在开发环境写入 Elementary 表或触发钩子)([FAQ](https://docs.elementary-data.com/oss/general/faq); [Slack 示例1](https://slack.com/archives/C02CTC89LAX/p1669760137760489); [Slack 示例2](https://slack.com/archives/C02CTC89LAX/p1677173051991689); [Slack 示例3](https://slack.com/archives/C02CTC89LAX/p1686675189142809); [Slack 示例4](https://slack.com/archives/C02CTC89LAX/p1666870092692679)).
l
@kapa.ai 为什么我设置成下面的,我配置+enabled: "{{ (target.name == 'prod') | as_bool }}"不运行钩子
Copy code
snowflake_profile:
  target: prod
  outputs:
    prod:
      type: snowflake
k
A message from kapa.ai
原因在于这条配置会“禁用整个 Elementary 包”,从而也不会执行 Elementary 的 on-run-end 钩子:
Copy code
yaml models:   elementary:     +enabled: "{{ (target.name == 'prod') | as_bool }}"
当 target.name 是 prod 时才启用 Elementary;若不是 prod,就整包禁用,因此钩子不跑。这是按环境停用 Elementary 的推荐方式之一,但副作用就是在被禁用的环境里不会有任何 Elementary 的模型/钩子执行(包括上传结果等)([FAQ 示例](https://docs.elementary-data.com/oss/general/faq); [Slack 确认用 +enabled 禁用整包](https://slack.com/archives/C02CTC89LAX/p1669760137760489))。 如果你的目标是“只在非 prod 不上传/不收集,但仍保留包可用”,不要用 +enabled 禁用整包,改用 vars 按环境关闭 hooks:
Copy code
yaml vars:   disable_run_results: "{{ target.name != 'prod' }}"   disable_tests_results: "{{ target.name != 'prod' }}"   disable_dbt_artifacts_autoupload: "{{ target.name != 'prod' }}"   disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}"
这样在 prod 目标下钩子会运行,在其他目标下钩子会被跳过(包本身仍启用,避免依赖/编译问题)([FAQ 推荐做法](https://docs.elementary-data.com/oss/general/faq); [Slack 建议用 vars 关闭钩子](https://slack.com/archives/C02CTC89LAX/p1680791210818739)).
l
@kapa.ai 那我不是用了target: prod吗?
k
A message from kapa.ai
是的,你在 profiles.yml 里把 target 设为 prod,那么运行时 target.name 就是 "prod"。但要区分两种配置目的: 1) 如果你用了
Copy code
yaml models:   elementary:     +enabled: "{{ (target.name == 'prod') | as_bool }}"
这表示“仅在 prod 启用 Elementary 包;非 prod 整包禁用”,被禁用时 Elementary 的模型与钩子都不会运行。这是按环境停用整包的做法(适用于只想在 prod 使用 Elementary)([FAQ 示例](https://docs.elementary-data.com/oss/general/faq); [Slack 确认用 +enabled 禁用整包](https://slack.com/archives/C02CTC89LAX/p1669760137760489))。 2) 如果你想在非 prod 保留包可用但不上传结果/不写库,应改用 vars 关闭钩子,而不是禁用整包:
Copy code
yaml vars:   disable_run_results: "{{ target.name != 'prod' }}"   disable_tests_results: "{{ target.name != 'prod' }}"   disable_dbt_artifacts_autoupload: "{{ target.name != 'prod' }}"   disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}"
这样 prod 会上传,非 prod 会跳过上传,但包与依赖仍能编译运行(避免本地/CI 报错)([文档中的推荐做法](https://docs.elementary-data.com/oss/general/faq); [相关 Slack 讨论与建议](https://slack.com/archives/C02CTC89LAX/p1680791210818739)).
l
@kapa.ai 那我不就是prod吗?怎么还是禁用了
k
A message from kapa.ai
可能原因有两类,建议逐一自查: - 表达式被当作字符串,未返回布尔值 早期/特定 dbt 版本里,如果写法不当会把结果当成字符串,导致 enabled 校验失败或评估为 False,从而“看起来被禁用”。请用这条经过社区验证的写法(注意没有 as_bool,且外层引号保持):
Copy code
yaml   models:     elementary:       +schema: elementary       +enabled: "{{ target.name == 'prod' }}"
有用户在 1.2.x/1.3.x 用这条后恢复正常(括号或 as_bool 会触发类型问题或错误求值)([示例1](https://slack.com/archives/C02CTC89LAX/p1677173051991689), [示例2](https://slack.com/archives/C02CTC89LAX/p1686675189142809)). - 你实际上不想“禁用整包” 配置 +enabled 会在非 prod 彻底禁用 Elementary(模型与钩子都不跑)。如果你的需求是“我在本地/PR 环境仍能编译,但不上传结果/不跑收集”,应改用 vars 关闭钩子,而不是禁用整包:
Copy code
yaml   vars:     disable_run_results: "{{ target.name != 'prod' }}"     disable_tests_results: "{{ target.name != 'prod' }}"     disable_dbt_artifacts_autoupload: "{{ target.name != 'prod' }}"     disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}"
这是官方在多次讨论中推荐的方式,能避免本地或 CI 因依赖 Elementary 表而编译失败,同时在非 prod 跳过上传与收集(钩子会执行检查,但不会写入)([讨论A](https://slack.com/archives/C02CTC89LAX/p1669625539486519), [讨论B](https://slack.com/archives/C02CTC89LAX/p1712570910953069), [讨论C](https://slack.com/archives/C02CTC89LAX/p1738778909958349)). 补充排查建议: - 确认当前运行的 target 的确是 prod(命令行没用 --target 覆盖,profiles.yml 的 target 指向 prod)([多次讨论示例](https://slack.com/archives/C02CTC89LAX/p1686675189142809)). - 确认 elementary 块放在 models 顶层,而不是嵌在其它模型命名空间下,否则配置不会生效(有用户因此无效)([案例](https://slack.com/archives/C02CTC89LAX/p1701110089154839)). - 若仍异常,先去掉 as_bool 与多余括号,按上面的最简写法验证。