Snowflake可运行的JavaScript UDF在Airflow中执行报错如何解决?
报错根本原因
问题出在函数体内的单引号和包裹整个JS代码块的外层单引号发生了转义冲突,导致Airflow向Snowflake提交SQL时,SQL字符串被提前截断,后面的JS代码被识别成了非法的SQL语法:
- 出错的
extract_vcode函数里,return s[0].split('=')[1];这行用了单引号包裹=,而函数体整体是用AS '...'单引号包裹的 - Airflow在解析传递这段SQL时,碰到
split('里的单引号会误认为是函数体字符串的结束符,把后面的内容直接拼接成SQL,就出现了你看到的截断后的非法语句 - 另一个能正常运行的
parse_metadata函数里所有字符串都用的双引号"",没有单引号冲突,所以执行正常
修复方案
任选一种即可,优先推荐方案3:
方案1:把函数体内的单引号全部替换为双引号
将split('=')改成split("=")即可,修改后完整代码:
CREATE OR REPLACE FUNCTION dfp.extract_vcode(NAME VARCHAR) RETURNS string LANGUAGE javascript STRICT AS ' const regex = /[[]v=([0-9]+)/ig; let s = NAME.match(regex); if (s != null) { return s[0].split("=")[1]; } else { return null; } ';
方案2:转义函数体内的单引号
如果要保留单引号写法,就在每个内部单引号前加一个单引号做Snowflake标准的SQL转义:把split('=')改成split(''='')。
方案3:用双美元符$$包裹函数体(更稳妥,完全避免引号冲突)
Snowflake支持用$$替代单引号包裹长字符串,不用额外处理内部的单双引号,改法如下:
CREATE OR REPLACE FUNCTION dfp.extract_vcode(NAME VARCHAR) RETURNS string LANGUAGE javascript STRICT AS $$ const regex = /[[]v=([0-9]+)/ig; let s = NAME.match(regex); if (s != null) { return s[0].split('=')[1]; } else { return null; } $$;
该方案兼容性最好,后续新增JS代码都不需要考虑引号转义问题。
内容的提问来源于stack exchange,提问作者KristiLuna
相关产品推荐
相关产品推荐

