dbt技术问题:如何在properties.yml中配置调用宏的post_hook?
在dbt的properties.yml中配置宏post_hook的解决方案
问题背景
现有apply_dbt_tags宏,在模型文件的内联config中通过post_hook调用时,可成功为Databricks物化表添加标签;但将该post_hook配置移至properties.yml时,先后出现model未定义和apply_dbt_tags未定义的编译错误。全局在dbt_project.yml配置该post_hook可正常生效,需实现单个模型在properties.yml中配置该宏post_hook的方案。
错误原因分析
model未定义错误:properties.yml的config渲染上下文与模型内联、全局配置不同,无参数宏中直接引用model变量会失效,因为该上下文不存在model对象。apply_dbt_tags未定义错误:宏未被dbt正确加载,比如宏文件未放在macros/目录下(dbt默认从该目录加载宏),或宏文件命名不符合规则(需为.sql后缀)。
可行解决方案
方案1:修正无参数宏并确保宏加载
步骤1:调整无参数宏代码
将宏中依赖model的部分替换为上下文可用的变量,改用config.get('tags', [])获取模型标签,this指代当前模型的relation:
{% macro apply_dbt_tags() -%} {% set tags_list = config.get('tags', []) %} ALTER TABLE {{ this }} SET TAGS ( {% for tag in tags_list -%} '{{ tag }}' {%- if not loop.last %}, {% endif -%} {%- endfor %} ) {%- endmacro -%}
步骤2:确保宏文件位置
将宏文件(比如命名为tags_macros.sql)放在项目根目录的macros/文件夹下,dbt编译时会自动加载该目录下的宏。
步骤3:properties.yml配置
直接调用宏即可:
models: - name: demo_apply_tags description: 将模型标签应用到Databricks表 config: tags: ["use", "force"] post_hook: "{{ apply_dbt_tags() }}"
方案2:使用带参数宏传递变量
如果偏好使用带参数的宏定义,可在properties.yml的post_hook中直接传递当前模型的this对象和标签列表:
带参数宏定义(无需修改)
{% macro apply_dbt_tags(relation, tag_list) -%} ALTER TABLE {{ relation }} SET TAGS ( {% for tag in tag_list -%} '{{ tag }}' {%- if not loop.last %}, {% endif -%} {%- endfor %} ) {%- endmacro -%}
properties.yml配置
models: - name: demo_apply_tags description: 将模型标签应用到Databricks表 config: tags: ["use", "force"] post_hook: "{{ apply_dbt_tags(this, config.get('tags', [])) }}"
这种方式无需依赖宏内部的上下文变量,直接显式传递参数,兼容性更强。
内容的提问来源于stack exchange,提问作者Merlin
相关产品推荐
相关产品推荐

