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

dbt同一SQL中连续调用宏报错:star宏期望Relation类型

解决dbt中宏调用时Macro star expected a Relation编译错误

错误根源

dbt_utils.star函数的from参数要求传入dbt Relation对象(比如ref()或source()返回的模型引用),但你在调用filtrar_colunas_star时,传入的是CTE名称Produtos——这只是一个字符串,不是dbt能识别的Relation对象,因此触发编译错误。另外,第二个宏嵌套了不必要的CTE结构,增加了编译复杂度。


解决方案1:重构宏+简化模型代码

步骤1:修改filtrar_colunas_star宏

让宏仅返回dbt_utils.star生成的列列表,而非完整查询:

{% macro filtrar_colunas_star(model_name, column_name) %}
    {{ dbt_utils.star(from=model_name, except=[column_name]) }}
{% endmacro %}

步骤2:修改Produtos_Sem_Tratamento.sql模型

直接在CTE中调用宏选择列,不再嵌套多余查询:

with
    Produtos as (
        {{ registros_recentes(ref('stg_Produtos'), 'id_produto', 'data_modificacao') }}
    ),

    final as (
        select {{ filtrar_colunas_star(ref('stg_Produtos'), "row_number") }}
        from Produtos
    )

select * from final

说明:这里传入ref('stg_Produtos')是因为dbt编译时只能获取已定义模型的元数据,CTE是动态生成的无法被star识别;而row_number是第一个宏新增的字段,except参数可以正常排除它。


解决方案2:合并宏逻辑(更简洁)

如果两个宏的逻辑紧密关联,可以直接在registros_recentes中完成列过滤,省去第二个宏:

{% macro registros_recentes(model_name, id_column_name, time_column_name) %}

with
    added_row_number as (
        select
            *
            ,row_number() over(partition by {{id_column_name}} order by {{time_column_name}} desc) as row_number
        from {{ model_name }}
    ),

    first_register as (
        select
            -- 直接用star排除row_number,无需额外宏
            {{ dbt_utils.star(from=model_name, except=['row_number']) }}
        from added_row_number
        where row_number = 1
    )

select * from first_register

{% endmacro %}

模型代码简化为:

select * from {{ registros_recentes(ref('stg_Produtos'), 'id_produto', 'data_modificacao') }}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:17:55