如何在dbt多模型中复用call statement生成的变量?
问题原因
dbt中每个模型都是独立的编译/执行单元,call statement()和load_result的作用范围仅限当前模型的上下文,跨模型后上下文不共享,所以直接调用load_result会返回None。
可行解决方案
方案1:封装成可复用宏
把查询变量的逻辑封装成宏,下游模型直接调用宏获取值,实现逻辑复用(注:每个模型调用时会单独执行一次查询)。
宏代码示例(macros/get_my_var.sql):
{% macro get_my_var() %} {%- call statement('call_test', fetch_result=True) -%} select col_1 from {{ ref('mrr_dwh__my_dim') }} where col_1 = 'US' {%- endcall -%} {%- set my_var = load_result('call_test')['data'][0][0] -%} {{ return(my_var) }} {% endmacro %}
下游模型调用示例:
select {{ get_my_var() }} as my_var
如果担心重复查询的性能,可以将源表mrr_dwh__my_dim设为增量模型,或者把宏的查询结果物化为小表后再取值。
方案2:创建共享模型存储变量
先构建一个专门存储该变量的模型,后续下游模型直接引用这个模型的结果,这种方式只会执行一次查询,性能更优。
共享模型示例(models/shared_my_var.sql):
select col_1 as my_var from {{ ref('mrr_dwh__my_dim') }} where col_1 = 'US'
下游模型引用示例:
select my_var from {{ ref('shared_my_var') }}
方案3:静态全局变量(仅适用于固定值场景)
如果变量值不需要动态查询,可直接在dbt_project.yml中配置全局变量:
vars: my_var: 'US'
模型中直接引用:
select {{ var('my_var') }} as my_var
内容的提问来源于stack exchange,提问作者Tomer Shalhon
相关产品推荐
相关产品推荐

