DBT dispatch方法未被编译器识别,跨方言函数适配求助
适配Snowflake SQL到DuckDB:endswith函数的宏分发问题
问题场景
原本为Snowflake编写的SQL代码需在兼容Postgres方言的DuckDB上运行,遇到函数适配问题:Snowflake支持endswith函数,但DuckDB/Postgres对应的是ends_with,报错如下:
Catalog Error: Scalar Function with name endswith does not exist!
Did you mean "ends_with"?
尝试的宏实现
我在macros/endswith.sql中编写了两种分发宏写法,但均未生效:
写法一(带return)
{% macro endswith (expr_1, expr_2) -%} {{ adapter.dispatch('endswith')(expr_1, expr_2) }} {%- endmacro %} {% macro default__endswith (expr_1, expr_2) -%} {{ return(dbt_utils.endswith(expr_1, expr_2)) }} {%- endmacro %} {% macro snowflake__endswith (expr_1, expr_2) -%} {{ return(dbt_utils.endswith(expr_1, expr_2)) }} {%- endmacro %} {% macro duckdb__endswith (expr_1, expr_2) -%} {{ return(ends_with(expr_1, expr_2)) }} {%- endmacro %} {% macro postgres__endswith (expr_1, expr_2) -%} {{ return(ends_with(expr_1, expr_2)) }} {%- endmacro %}
写法二(直接返回字符串)
{% macro endswith (expr_1, expr_2) -%} {{ adapter.dispatch('endswith')(expr_1, expr_2) }} {%- endmacro %} {% macro default__endswith (expr_1, expr_2) -%} dbt_utils.endswith(expr_1, expr_2) {%- endmacro %} {% macro snowflake__endswith (expr_1, expr_2) -%} dbt_utils.endswith(expr_1, expr_2) {%- endmacro %} {% macro duckdb__endswith (expr_1, expr_2) -%} ends_with(expr_1, expr_2) {%- endmacro %} {% macro postgres__endswith (expr_1, expr_2) -%} ends_with(expr_1, expr_2) {%- endmacro %}
两种写法均无语法错误,但编译后输出仍然是原endswith函数,运行时依旧报错。推测是宏可见性问题,但删除该宏会导致依赖缺失。
其他尝试
- 参考官方文档配置dispatch:
dispatch: - macro_namespace: dbt_utils search_order: ['my_project', 'dbt_utils']
理论上无需此配置,但尝试后无效果。
- 仿照dbt_utils源码修改为
adapter.dispatch('endswith', 'dbt_utils'),同样无效。 - 重装适配器、更新dbt至实验版本、调整profile配置(profile内容如下):
duck_db:
target: dev
outputs:
dev:
type: duckdb
path: '~/data/mock.db'
extensions:
- httpfs
- parquet
提问
目前已无其他解决思路,请问应如何正确使用adapter来解决该问题?
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

