You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

dbt中pre_hook传递宏变量异常:get_date返回值未正确传入insert_table

问题原因与解决方案

原因分析

dbt存在两个核心执行阶段,这是问题的关键:

  • 项目解析阶段:dbt读取所有模型配置、渲染宏的静态内容,此时execute变量为False——因为还未开始执行任何SQL操作。
  • 模型执行阶段:dbt开始运行模型对应的SQL逻辑,此时execute变量为True,可以执行数据库查询。

你的代码存在执行时机不匹配的问题:

  1. 模型里的{% set my_date = get_date() %}是在模型执行阶段运行的,此时execute=True,能正确获取数据库中的最新日期2024-05-05。
  2. 但你用字符串拼接的方式把insert_table宏写在pre_hook中,这部分配置会在项目解析阶段被渲染。此时调用get_date()时execute=False,只能返回默认值2024-04-01,这个值被硬编码进了pre_hook的SQL中,和模型执行阶段的my_date完全无关。

解决方法

以下是两种可靠的修正方式:

方法一:让insert_table宏内部动态获取日期

修改insert_table宏,让它自己调用get_date()获取日期,确保在执行阶段才查询数据库:

{% macro insert_table(pre_hook=false) %}  
{% if execute %}
{% set report_date = get_date() %}
insert into public.my_table
    values ('{{ report_date }}', current_timestamp, 0) 
{% endif %} 
{% endmacro %}

模型配置简化为直接调用宏:

{{
    config(
      pre_hook=[ 
       "{{ insert_table(pre_hook=True) }}"
          ]
    )
}}

方法二:将pre_hook改为执行阶段渲染的Jinja表达式

去掉pre_hook的字符串包裹,直接传递Jinja表达式,让它在模型执行阶段才渲染:

{{
    config(
      pre_hook=insert_table(report_date=get_date(), pre_hook=True)
    )
}}

这种写法下,insert_table宏会在execute=True的阶段被调用,get_date()能正确返回数据库中的最新日期。

内容的提问来源于stack exchange,提问作者MADAO_MAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:22:45