从包含没有分隔符的json对象的文件中加载数据

问题描述 投票:0回答:2

我正在尝试将s3中文件中的数据加载到雪花中。由于无法控制的原因,这些文件的内容是不带分隔符的JSON对象,例如,单个文件将是这样的:{"key1":"valueA","key2":"valueB"}{"key1":"valueC","key2":"valueD"}

所以我无法使用任何分隔符创建文件格式。我曾想过使用'}{',然后用缺少的括号包装两个记录(JSON对象),但是没有这样的选项,并且记录定界符接受单个char。另一种方法可能是使用正则表达式捕获单个记录,但我在文档中看不到任何内容。

有没有更好的方法来解决这个问题?

snowflake-datawarehouse
2个回答
1
投票

由于文件整体上不是有效的JSON,因此您不能将其读取为半结构化数据。

如果对象在内部'}'字符处分割,则可以读取CSV格式的文件并稍加巧妙地重新组装:

CREATE OR REPLACE TABLE T (
  LINE_NO NUMBER IDENTITY,
  JSON TEXT
);

COPY INTO T(JSON) FROM (SELECT $1||'}' JSON FROM @my_stage/json.csv)
FILE_FORMAT = (TYPE = CSV FIELD_DELIMITER = NONE RECORD_DELIMITER='}');

SELECT REC_NO, LISTAGG(JSON) WITHIN GROUP (ORDER BY LINE_NO) JSON FROM (
  SELECT
    SUM(CASE WHEN NEW_OBJ AND MOD(QUOTE_QTY_AGG - QUOTE_QTY, 2) = 0 THEN 1 ELSE 0 END)
        OVER (ORDER BY LINE_NO) REC_NO, LINE_NO, JSON
  FROM (
    SELECT
      REGEXP_COUNT(JSON, '(\\\\.|[^"])*"') QUOTE_QTY,
      SUM(REGEXP_COUNT(JSON, '(\\\\.|[^"])*"')) OVER (ORDER BY LINE_NO) QUOTE_QTY_AGG,
      REGEXP_LIKE(JSON, '\\s*\\{\\s*".*') NEW_OBJ,
      LINE_NO, JSON
    FROM T
  )
)
GROUP BY REC_NO
ORDER BY REC_NO;

上面的查询将(在这里伸出我的头)解析any“有效”(对多个对象取模)JSON,甚至是像{"{a}": "{{b}}"}这样的对象。通过观察以下内容来做到这一点:

  • JSON部分以{"开头,是新对象的候选者
  • JSON部分不在字符串内开始(直到行首为止,偶数个未分隔的双引号字符都保持不变)

0
投票

Hans的方法可以奏效,但这确实是一个(不错!)技巧。

有一种更简单的方法if,文件不会太大(最多几兆字节)。

然后,您可以将整个文件读取为单个varchar值,并使用以下内容对其进行后处理。简而言之,我们

  • }{分割字符串
  • “根据需要修复”缺少的冰壶
  • parse_json结果:

这里是代码:

create or replace table x(v varchar) as 
  select * from values('{"a":1}{"b":2}{"c":{"cc":3}}');

select parse_json(
  concat(
    iff(startswith(spl.value,'{'), '', '{'),  -- add '{' if needed 
    spl.value,
    iff(endswith(spl.value, '}'), '', '}')  -- add '}' if needed
  )
) rec 
from x, lateral split_to_table(v, '}{') spl;
-------------+
     REC     |
-------------+
 {           |
   "a": 1    |
 }           |
 {           |
   "b": 2    |
 }           |
 {           |
   "c": {    |
     "cc": 3 |
   }         |
 }           |
-------------+
© www.soinside.com 2019 - 2024. All rights reserved.