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
相关产品推荐
相关产品推荐

