dbt macro是否支持将其他macro作为参数传入使用
问题解答
1. 传入macro作为参数的合法性
你给出的写法完全可以在dbt框架中正常运行。dbt基于Jinja2引擎实现macro能力,macro本质就是可调用的函数对象,天然支持将macro作为参数传入另一个macro的高阶函数用法。
2. 向作为参数的macro传递参数的方法
固定参数场景
如果外层macro已经明确知道传入的目标macro需要的参数数量,直接在调用时传入对应参数即可,和你示例中的写法一致,参考完整可运行的示例:
首先定义待传入的目标macro:
{% macro calc_revenue(price_col, quantity_col) %} {{ price_col }} * {{ quantity_col }} {% endmacro %}
定义接收macro作为参数的外层macro:
{% macro calculate_order_metric(col1, col2, metric_calculator) %} select order_id, {{ metric_calculator(col1, col2) }} as metric_result from your_order_table {% endmacro %}
调用外层macro时直接传入目标macro的名称即可:
{{ calculate_order_metric('unit_price', 'sales_qty', calc_revenue) }}
可变参数场景(对应R语言的...透传逻辑)
如果需要兼容不同参数数量的目标macro,可以用Jinja2的可变位置参数*args和可变关键字参数**kwargs实现参数透传,和R的...逻辑完全一致:
{% macro macro_caller(target_macro, *args, **kwargs) %} -- 所有传入的参数都会透传给目标macro {{ target_macro(*args, **kwargs) }} {% endmacro %}
使用时不管目标macro需要多少参数都可以直接传递:
-- 示例:目标macro需要3个参数 {% macro calc_profit(price_col, qty_col, cost_col) %} ({{ price_col }} - {{ cost_col }}) * {{ qty_col }} {% endmacro %} -- 调用透传macro {{ macro_caller(calc_profit, 'unit_price', 'sales_qty', 'unit_cost') }}
注意事项
- 传入macro作为参数时,不需要用
{{ }}包裹,也不要加括号触发调用,直接写macro的名称即可 - 如果目标macro来自第三方dbt包,需要传入完整的命名空间路径,例如
dbt_utils.date_spine
内容的提问来源于stack exchange,提问作者Reid Williams
相关产品推荐
相关产品推荐

