postgresql 编译器看不到DBT分派方法

yhived7q  于 12个月前  发布在  PostgreSQL
关注(0)|答案(3)|浏览(122)

我正在使用DuckDB(Postgres)方言的数据库上运行为Snowflake SQL方言编写的代码。我需要调度目标中不存在的函数。例如,我有关于endswith函数的错误-它在Snowflake中可用,但在Postgres中它是ends_with。这就是错误的样子:
您访问的页面不存在!
你的意思是“结束于”?
所以我写了一个dispatcher方法,并将其存储在macros/endswith.sql中:

{% 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 %}


它不会抛出错误,但也不会被编译器看到。当我编译时,我在输出中得到正常的结束,当我运行时,我得到了和我一样的错误。
我预计可能是宏可见性有问题,但当我从目录中删除一些宏时,我缺少依赖项。
有3个网站有相关文件:

  1. about dispatch config
  2. dispatch
  3. enter link description here
    他们提供了这个工具:
dispatch:
  - macro_namespace: dbt_utils
    search_order: ['my_project', 'dbt_utils']


从理论上讲,这应该是不必要的,因为默认方法应该是我的项目文件夹中的一个,但我试过了,它没有改变任何东西(也许我做错了?)。为了帮助它,我还尝试了dbt_utils源代码中可见的内容:

adapter.dispatch('endswith', 'dbt_utils')


但它也没有改变任何东西。在试用期间,我重新安装了适配器,将dbt也更新为实验版本,使用profile进行操作。我仍然不确定dbt是否知道目标方言是什么,但我假设它是由profile选择的,在我的情况下看起来像这样:
duck_db:target:dev outputs:dev:type:duckdb path:'dock/data/mock.db' extensions:- httpfs - parquet
在这一点上,我没有任何其他的想法如何解决这个问题。我应该如何使用适配器?

esyap4oy

esyap4oy1#

dbt-duckdb开发人员在这里。我认为adapter.dispatch的语法需要像这样:

{% macro endswith (expr_1, expr_2) -%}
    {{ return(adapter.dispatch('endswith')(expr_1, expr_2)) }}
{%- endmacro %}

字符串
也就是说,return语句在这里做了实际的工作,我认为你不能忽略它。

iezvtpos

iezvtpos2#

通过检查audit_helper包的例子,很明显,它们的函数中没有return语句意味着根本原因可能存在于其他地方。

{% macro get_columns_in_relation_sql(relation) %}

{{ adapter.dispatch('get_columns_in_relation_sql', 'audit_helper')(relation) }}

{% endmacro %}

字符串
那么像这样运行一个自定义适配器调度呢:

{% macro endswith(expr_1, expr_2, adapter='default') -%}
    {%- if adapter == 'default' -%}
        {{ return(dbt_utils.endswith(expr_1, expr_2)) }}
    {%- elif adapter == 'snowflake' -%}
        {{ return(dbt_utils.endswith(expr_1, expr_2)) }}
    {%- elif adapter == 'duckdb' -%}
        {{ return(ends_with(expr_1, expr_2)) }}
    {%- elif adapter == 'postgres' -%}
        {{ return(ends_with(expr_1, expr_2)) }}
    {%- else -%}
        {{ return('Unsupported adapter') }}
    {%- endif -%}
{%- endmacro %}

liwlm1x9

liwlm1x93#

OP:
更新:我几乎可以肯定这个问题已经通过安装postgres adapter沿着duck one解决了。调度器已经内置在dbt中,没有必要作为一个单独的宏编写。
上一页:我不知道这是否是正确的解决方案,因为它导致了另一个错误,但就目前而言,编译器可以看到宏(这会引起宏名称重复错误)-问题是我没有将endswith添加到models.yml文件中。此外,当我错误地修改它时-没有指定参数-没有错误,但编译器没有看到它。
我目前的理论是,新的错误(每个调度器选项分开)是由于已经有一些内置的endswith调度器,而dbt编译器不知道它应该使用它(我在项目文件和外部库中找不到它)。

相关问题