尝试将 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" }
这是有效的 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 ...
这是我试图在 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" } |