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

Posted

技术标签:

【中文标题】Python Glue 作业 - 雪花存储过程未返回确切的错误消息【英文标题】:Python Glue job - Snowflake stored procedure not returning exact error message 【发布时间】:2021-11-18 07:22:06 【问题描述】:

我正在尝试通过 python 胶水作业执行雪花存储过程,但是当我在存储过程中的 SQL 语句中遇到任何错误时,我希望该过程退出并且胶水作业应该失败。

我在雪花存储过程中使用此代码:

create or replace procedure schema.PROC_TEST 
    (input_sql varchar(16777216))
returns string not null
language javascript
as
$$
snowflake.execute(sqlText:`BEGIN TRANSACTION;`);
try
                
                    var QueryExec = INPUT_SQL+ ";";
                    var QueryResult = snowflake.execute(sqlText: QueryExec);
                
                catch (err)                                     // Catching any error if occurs in INPUT_SQL
                
                    result = 'Error: ' + err;
                    snowflake.execute(sqlText:`ROLLBACK;`);
                    return result;
                    throw err.message;
                
$$;

现在如果我通过如下输入查询(这里proc_test_final1 是一个不正确的表名):

insert into schema.proc_test_final1 
    select id, name, sal 
    from schema.proc_test_src;

该过程不会引发错误“不正确的表名”,而是返回类似的一般错误

错误:090232 (25000):存储过程执行错误:在存储过程中启动的作用域事务不完整,已回滚

我认为这可能是因为 ROLLBACK 命令,所以我尝试删除该命令,但仍然失败并出现上述相同的错误。我还尝试在 catch 块中删除结果变量,但仍然捕获到上述错误。

我想在胶水作业中捕捉到确切的特定 SQL 错误(语法错误/代码错误)。

下面是我发现错误的胶水作业代码:

input_sql = 'insert into schema.proc_test_final1 select id, name, sal from schema.proc_test_src'
try:
    f_CallProc = "call TEST_PROC('"+input_sql+"');"
    cur.execute(f_CallProc)
    print(cur.fetchall())
    cur.close()
    ctx.close()

except snowflake.connector.errors.ProgrammingError as err:
    print('Error: 0 (1)'.format(err.msg, err.sfqid))
    cur.close()
    ctx.close()
    sys.exit(1)

【问题讨论】:

【参考方案1】:

当您运行具有显式 START TRANSACTION 但没有显式“ROLLBACK”或“COMMIT”的 SP 时,将发生错误“Scoped transaction started in stored procedure is incomplete and it was rolled back”。

在我的测试中,如果我没有以下行:

snowflake.execute(sqlText:`ROLLBACK;`);

您的 SP 将因此类错误而失败。

但是,当我有这一行时,它将失败并出现以下错误:

Error: SQL compilation error:
Schema 'ERICLIN.SCHEMA' does not exist or not authorized.

我认为这就是你所追求的。

你能再检查一下你的SP吗?您是否复制并粘贴了正确的?

顺便说一句,你原来的 SP 不会运行,因为没有名为“input_sql”的变量,它应该是“INPUT_SQL”,因为 Snowflake 的 SP 中的每个变量都是大写的。

===========================

更新

请看下面的执行输出:

create or replace procedure PROC_TEST 
    (input_sql varchar(16777216))
returns string not null
language javascript
as
$$
    snowflake.execute(sqlText:`BEGIN TRANSACTION;`);
    try 
        var QueryExec = INPUT_SQL + ";";
        var QueryResult = snowflake.execute(sqlText: QueryExec);
    
    catch (err)  
        result = 'Error: ' + err;
        snowflake.execute(sqlText:`ROLLBACK;`);
        return result;
    
$$;
call PROC_TEST('insert into schema.proc_test_final1 select id, name, sal from schema.proc_test_src');

+-----------------------------------------------------------+
| PROC_TEST                                                 |
|-----------------------------------------------------------|
| Error: SQL compilation error:                             |
| Schema 'ERICLIN.SCHEMA' does not exist or not authorized. |
+-----------------------------------------------------------+

如果没有 ROLLBACK 调用,它将产生与您相同的错误:

create or replace procedure PROC_TEST 
    (input_sql varchar(16777216))
returns string not null
language javascript
as
$$
    snowflake.execute(sqlText:`BEGIN TRANSACTION;`);
    try 
        var QueryExec = INPUT_SQL + ";";
        var QueryResult = snowflake.execute(sqlText: QueryExec);
    
    catch (err)  
        result = 'Error: ' + err;
        return result;
    
$$;
call PROC_TEST('insert into schema.proc_test_final1 select id, name, sal from schema.proc_test_src');

090232 (25000): Stored procedure execution error: Scoped transaction started in stored procedure is incomplete and it was rolled back.

【讨论】:

是的@EricLin,它是正确的 SP。我已经更正了 input_sql,因为这是一个错字。但是,我应该包括“BEGIN TRANSACTION”吗?在 try 块内以捕获错误?你可以发布你的代码吗?另请注意:我在插入语句之前有一个截断表语句。 刚刚更新了我的回答。

以上是关于Python Glue 作业 - 雪花存储过程未返回确切的错误消息的主要内容,如果未能解决你的问题,请参考以下文章

SMTP:邮件未通过 AWS Glue Python 作业发送

如何使用 AWS Glue 运行任意/DDL SQL 语句或存储过程

Python/Pyspark 迭代代码(用于 AWS Glue ETL 作业)

如何配置 Spark / Glue 以避免在 Glue 作业成功执行后创建空的 $_folder_$

每次我从 Python 库路径调用 .egg 时,AWS Glue 作业都会崩溃

雪花 Python 连接器未与 AWS 胶水 Python 外壳连接