雪花存储过程从 dbt 失败

Posted

技术标签:

【中文标题】雪花存储过程从 dbt 失败【英文标题】:Snowflake stored procedure fails from dbt 【发布时间】:2021-09-14 09:31:34 【问题描述】:

我在通过 dbt 在 Snowflake 中执行存储过程时遇到问题:

我的过程的描述是这样的:MyStoredProcedure(ARRAY, VARCHAR, VARCHAR)

所以,当我想运行它时,我使用 array_construct 函数来创建第一个参数,例如: call MyStoredProcedure(array_construct(array_construct('str_1', 'str_2')), 'schema_name', 'table_name');

这在我在 Snowflake 中运行时有效。但是,当我从 dbt 运行它时,它会失败并出现以下错误:

不允许修改在不同范围开始的事务。

我确信这与在此调用中调用 array_construct 有关。

我应该提到,要从 dbt 运行它,我已经定义了一个这样的宏:

% macro MyStoredProcedure() %
    % set query -%
        CALL MyStoredProcedure(
           array_construct(array_construct('str_1', 'str_2')),
           'schema_name',
           'table_name');
    %- endset %

    % do run_query(query) %
% endmacro %

当然像这样运行它:dbt run-operation MyStoredProcedure

感谢任何可以帮助我解决此问题的提示或想法。

谢谢

【问题讨论】:

最终我通过在过程定义中将 ARRAY 参数的类型更改为 VARCHAR 解决了我的问题,然后我在 javascript 部分实现了一个逻辑,将参数从 VARCHAR 转换为ARRAY,就像使用 'split()' 函数。 【参考方案1】:

我仍然非常了解雪花,但通过阅读 this section 在文档中,在我看来,这可能只是您的多范围过程调用的机制。

据我所知,在雪花中执行此操作的典型(非 dbt)方式是:

begin transaction;
insert 1; 
call storedprocedure();
insert 2;
commit;

也许您可以像这样调整宏来克服范围嵌套问题,因为一切都将在一个事务中完成?

% macro MyStoredProcedure() %

    % set query -%
        begin transaction;
        CALL MyStoredProcedure(
           array_construct(array_construct('str_1', 'str_2')),
           'schema_name',
           'table_name');
        commit;
    %- endset %

    % do run_query(query) %
% endmacro %

无法对此进行测试,因为我无法重现该过程本身。

【讨论】:

我已经尝试过您的解决方案,但仍然遇到相同的错误。虽然你的建议很有道理。 @Bardia 有什么不同?所有权?自从我回答以来,我的经验是检查: 1. dbt/snowflake 将 proc 扔到哪里去了? 2. dbt 用户是否拥有运行 proc 的所有权/权限?以及其他一些类似的事情。 唯一的区别是我从你的代码中删除了“开始交易”;因此它不会启动新事务,但应提交每个调用。【参考方案2】:

最终我让它运行如下:

% macro MyStoredProcedure() %
    % set query -%
        CALL MyStoredProcedure(
            array_construct(array_construct('str_1', 'str_2')),
            'schema_name',
            'table_name');
        commit;
    %- endset %

    % do run_query(query) %
% endmacro %

【讨论】:

以上是关于雪花存储过程从 dbt 失败的主要内容,如果未能解决你的问题,请参考以下文章

Python Glue 作业 - 雪花存储过程未返回确切的错误消息

使用 Liquibase 创建雪花存储过程

雪花程序因任务执行而失败

可以从雪花中的函数调用存储过程吗

我们可以使用雪花中的存储过程将文件从文件位置加载到命名内部阶段吗?

雪花存储在使用抛出错误而不是返回错误时给出不同的错误