在 Snowflake 中读取 JSON 文件

Reading JSON files in Snowflake

提问人:ffi23 提问时间:11/18/2023 更新时间:11/18/2023 访问量:19

问:

我在这方面浪费了很多时间,但我仍然不明白如何正确地做到这一点,以及如何在它不起作用时对其进行故障排除。有时,当我幸运的时候,它会起作用。

大多数情况下,我从 Snowflake 收到“解析 json 时出错”(100069 (22P02):解析 JSON 时出错:文档太大,最大大小 16777216 字节)。

我正在尝试加载 geojson 文件,但我对普通 json 文件也有类似的问题。在本例中,我的文件如下所示:

{
"type": "FeatureCollection",
"name": "myshapefileinjson",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "fid": 1, "string_id": "111011" etc..}
{ "type": "Feature", "properties": { "fid": 2, "string_id": "1110114" etc..}
...
]

我正在尝试将其加载到 Snowflake 中,每个功能一行,如下所示:

copy into raw.myschema.mytable
from (
  select 
    $1
  from @my_aws_s3_stage/myfile.geojson.gz
)
file_format = (type = JSON, strip_outer_array = True) 

为什么它不起作用?当我收到此错误时,如何解决问题?我知道 Snowflake 正在尝试将整个文件加载到同一行中,但我不明白为什么。

json snowflake-cloud-data-platform geojson

评论

0赞 NickW 11/18/2023
嗨 - 您希望 json 层次结构中存在于高于功能级别的 type、name 和 crs 属性会发生什么?
0赞 Greg Pavlik 11/18/2023
copy 语句显示,但示例没有外部数组。如果这些文件大于 16mb 并且没有外部数组或格式化为 JSONL,则需要对其进行预处理。JSONL 可以使用读取整行并使用该函数将每行转换为变体的文件格式进行处理。strip_outer_array = Trueparse_json
0赞 ffi23 11/20/2023
嗨,@NickW,我不在乎类型、名称和 crs 属性。我希望这会忽略它们,直接进入我关心的阵列。@Greg帕夫利克的评论让我觉得我错了?strip_outer_array = True
1赞 NickW 11/20/2023
嗨 - 是的,不幸的是这行不通,您需要从“功能”作为外部数组开始。不知道它是否有效,但也许从带有条带外部数组选项的“SELECT $1:features”开始
1赞 NickW 11/20/2023
Snowflake 确实支持 geojson 文件;它不支持将超过 16MB 的文件(任何类型)加载到单个变体列中。您需要按照@GregPavlik建议对文件进行预处理,以从文件中删除前 3 个属性(您不需要的属性),以便有一个 SF 可以剥离的外部数组,从而成功地将文件处理成多行

答:

0赞 ffi23 11/21/2023 #1

回答我自己的问题:

  1. 尽管 Snowflake 声称他们支持 geoJSON,但文档并未明确说明存在关键限制:您的 geoJSON 文件将在一行中全部读取,因此您只能单独使用不超过 16MB 的 geoJSON 文件。这是因为 Snowflake 无法剥离所有标准 geoJSON 文件中的 head 字典(这部分:
{
"type": "FeatureCollection",
"name": "myshapefileinjson",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": ...
}
  1. 对我来说,最简单的解决方案是将 geoJSON 文件转换为 geoJSONSeq,这会去除 JSON 字典。geoJSONSeq 是数组中的一系列 JSON 要素。这正是 Snowflake 想要的,它将读取任何文件大小,如果您将 .我在 Python 中使用 GeoPandas 通过运行以下行进行了此转换:,但您可以使用其他工具保存为此格式。strip_outer_array = Truemygeodataframe.to_file(myfile.geojson', driver = 'GeoJSONSeq')

总而言之,尽管 Snowflake 吹嘘他们支持 geoJSON,但实际上不可能找到如何做到这一点的好例子,他们应该在他们的文档中明确说明文件大小限制为 16MB。解决方案是使用 geoJSONSeq。