尝试将 parse_json 与有效 JSON 一起使用时出现雪花错误 - 解析 JSON 时出错:缺少逗号,第 6 行,第 17 位

Snowflake error when trying to use parse_json with valid JSON - Error parsing JSON: missing comma, line 6, pos 17

这是有效的 JSON(我 运行 它针对两个 JSON 验证器并且还使用 powershell 解析它):

{
    "actionCD": "error",
    "NotesTXT": "\"Exception call timeout\""
}

这是无效的JSON:

{
    "actionCD": "error",
    "NotesTXT": "\"Exception call timeout\""
}

但是,parse_json 函数在第一个示例中失败:

SELECT '{ "actionCD": "error", "NotesTXT": "\"Exception call timeout\"" }' as json_str
,PARSE_JSON(json_str) as json;

Error parsing JSON: missing comma, pos 38

而且出乎意料的是,雪花 parse_json 函数适用于 无效 json:

SELECT '{ "actionCD": "error", "NotesTXT": "\"Exception call timeout\"" }' as json_str
,PARSE_JSON(json_str) as json;

<No Errors>

这让我对如何进行感到非常困惑和不确定。我正在以编程方式使用 powershell 创建有效 JSON,然后尝试使用 INSERT INTO ()...SELECT ...

valid JSON 插入雪花中

这是我试图在 powershell 中构建的插入语句:

INSERT INTO DBNAME.SCHEMANAME.TABLENAME(
        RunID
       ,jsonLogTXT
        
     ) SELECT
       '$RunID'
       ,parse_json('$($mylogdata | ConvertTo-Json)')
     ;


# where $($mylogdata | ConvertTo-Json) outputs valid json, and from time-to-time includes \" to escape the double quotes. 
# But snowflake fails because snowflake wants \" to escape the double quotes.

这是预期的吗? (显然我发现它出乎意料:-))。这里有什么建议? (在将它发送到 snowflake 之前,我是否应该在 powershell 中搜索我的 json-stored-as-a-string 以查找“并将其替换为 \”?不过感觉真的很糟糕?)

这在很大程度上是意料之中的。在 JSON 解析发生之前,Snowflake 字符串使用反斜杠作为转义字符。

因此:"\"content\"" 将被 snowflake 解析为 "\"content\"",这将被送入 JSON 解析器,并被视为有效 JSON。

类似的问题可以用单引号来解决。

在发送到 snowflake 之前将 \ 替换为 \ 可能会奏效,尽管当我 运行 遇到这些类型的问题时,我发现它通常伴随着其他 encryption/parsing 错误。例如,我发现更改方法并让 snowflake 解析具有 JSON 的文件通常更合适。然后你就没有额外的转义字符了。不过,这对您的流程来说是一个更大的变化。

Snowflake 的文档在此处有关于此主题的快速说明:https://docs.snowflake.com/en/sql-reference/functions-regexp.html#escape-characters-and-caveats

您发布的代码显示了答案:

SELECT '{ "actionCD": "error", "NotesTXT": "\"Exception call timeout\"" }' as json_str
,PARSE_JSON(json_str) as json;
JSON_STR JSON
{ "actionCD": "error", "NotesTXT": ""Exception call timeout"" } { "NotesTXT": ""Exception call timeout"", "actionCD": "error" }

您看到的不是“您输入的”,因此 PARSE_JSON 解析的是您注意到的“有效 JSON”

答案对于许多计算机环境来说很常见,那就是环境正在读取您的输入,并且它会作用于其中的一部分,因此 SQL 解析器正在读取您的 SQL 并且它在有效 json 中看到单个 \ 并认为您正在启动转义序列,然后抱怨逗号在错误的位置。

BASH(或 PowerShell)、Python,甚至 Java 都要求您了解字符串内容(也就是有效的 JSON)和你必须如何表示它才能通过语言解析器。

那么应该如何“在雪花中插入 JSON”,如果它的容量很大,一个普遍的答案不是通过 INSERT 命令。或者,如果您不想使字符串解析器安全,您可以对数据进行 BASE64 编码(在 powershell 中)并插入 base64_decode(awesomestring)

看起来像 eyAiYWN0aW9uQ0QiOiAiZXJyb3IiLCAiTm90ZXNUWFQiOiAiXCJFeGNlcHRpb24gY2FsbCB0aW1lb3V0XCIiIH0= 因此

SELECT PARSE_JSON(base64_decode_string('eyAiYWN0aW9uQ0QiOiAiZXJyb3IiLCAiTm90ZXNUWFQiOiAiXCJFeGNlcHRpb24gY2FsbCB0aW1lb3V0XCIiIH0=')) as json_from_B64;

给出:

JSON_FROM_B64
{ "NotesTXT": ""Exception call timeout"", "actionCD": "error" }