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

如何将dbt宏传入模型配置并在自定义物化中执行?

问题描述

我尝试按如下方式将dbt宏传入模型配置:

{{ config(
custom_macro=my_macro
)
}}

其中my_macro定义在/macros/my_macro.sql文件中。

随后我尝试在自定义物化中运行该宏:

{% if config.get("custom_macro", None) %}
        {% do my_macro('foo') %}
{% endif %}

但在编译阶段出现错误:
TypeError: can not serialize 'MacroGenerator' object

之后我尝试传入宏名称字符串,并使用adapter.dispatch或ref()等方法,但均未成功。

请问如何正确传递宏对象,或如何按宏名称动态执行宏?

解决方案

方式一:通过上下文对象动态获取宏执行

在模型配置里传入宏的名称字符串:

{{ config(
    custom_macro='my_macro'
) }}

在自定义物化中,利用dbt全局context对象获取宏实例并执行:

{% set macro_name = config.get("custom_macro") %}
{% if macro_name %}
    {% set target_macro = context.get(macro_name) %}
    {% do target_macro('foo') %}
{% endif %}

context可以直接通过宏名称字符串匹配到对应的MacroGenerator实例,避开序列化问题。

方式二:使用adapter.dispatch(官方推荐多场景方案)

如果需要适配多数据平台,优先用这种方式:

  1. 先定义带dispatch标识的宏(/macros/my_macro.sql):
{% macro my_macro(arg) %}
    {{ return(adapter.dispatch('my_macro')(arg)) }}
{% endmacro %}

-- 默认平台实现示例
{% macro default__my_macro(arg) %}
    {{ log('执行my_macro,参数:' ~ arg, info=True) }}
{% endmacro %}
  1. 模型配置传入宏名称:
{{ config(
    custom_macro='my_macro'
) }}
  1. 自定义物化中调用:
{% set macro_name = config.get("custom_macro") %}
{% if macro_name %}
    {% do adapter.dispatch(macro_name)('foo') %}
{% endif %}

该方式天然支持多平台适配,符合dbt最佳实践。

错误原因说明

dbt编译时会序列化模型配置,MacroGenerator是dbt内部的宏对象,无法被序列化成可存储格式,因此直接传入宏对象会触发序列化错误,必须传递字符串名称再动态获取执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:13:16