如何通过DBT on-run-start运行宏并设置全局run_date变量
解决方案:全局复用格式化后的run_date变量
1. 优化宏直接生成YYYY-MM-DD字符串
先修改你的get_run_date宏,直接对run_started_at做字符串格式化,避免生成Date('时间戳')的形式:
{% macro get_run_date() %} '{{ run_started_at.strftime("%Y-%m-%d") }}' {% endmacro %}
编译后会直接输出'2024-05-20'这类字符串,可直接在SQL中当作日期值使用。
2. 全局设置变量(无需每个SQL文件重复操作)
方式一:用预钩子全局初始化变量
在dbt_project.yml中添加on-run-start预钩子,在所有模型执行前全局设置run_date变量:
on-run-start: - "{% set run_date = run_started_at.strftime('%Y-%m-%d') %}"
之后所有SQL模型里直接使用{{ run_date }}即可,无需每个文件单独定义或调用宏。
方式二:支持shell传参的全局变量方案
如果需要通过shell脚本回填历史数据时指定日期,可结合自定义变量+宏实现:
- 在
dbt_project.yml中定义默认变量:
vars: run_date: null
- 修改宏优先读取传入的变量,无传入值时用
run_started_at:
{% macro get_run_date() %} {% if var('run_date') %} '{{ var('run_date') }}' {% else %} '{{ run_started_at.strftime("%Y-%m-%d") }}' {% endif %} {% endmacro %}
- 全局复用:可以通过预钩子把变量全局化,或者直接在SQL中调用
{{ get_run_date() }}。
3. Shell脚本传参回填数据
运行dbt时通过--vars参数传入指定日期,宏会自动优先使用该值:
dbt run --vars '{"run_date": "2024-05-10"}'
为什么之前的方法报错?
- 用
{% set... %}结合run_query报错:run_query是运行时执行的操作,而set是编译时变量赋值,两者执行阶段冲突,无法混用。 project.yml中直接设置变量未识别宏:vars里的内容是静态字符串,无法直接调用Jinja宏,必须通过宏逻辑来读取变量或 fallback 到run_started_at。
内容的提问来源于stack exchange,提问作者coder_bob
相关产品推荐
相关产品推荐

