使用JSONPath对缺少的数组/字段进行Redshift COPY

时间:2018-12-13 19:22:51

标签: amazon-redshift jsonpath

我正在使用COPY命令将JSON数据集从S3加载到Redshift表。数据正在部分加载,但是会忽略缺少数据(键值/数组)的记录,即从下面的示例中,仅第一个记录将被加载。

查询:

  

从's3://mybucket/address.json'复制地址
  凭证'aws_access_key_id = XXXXXXX; aws_secret_access_key = XXXXXXX'   maxerror为250
  json's3:/mybucket/address_jsonpath.json';

我的问题是,即使某些记录缺少键/数据,也如何从address.json加载所有记录,类似于下面的示例数据集。

JSON示例

{
  "name": "Sam P",
  "addresses": [
    {
      "zip": "12345",
      "city": "Silver Spring",
      "street_address": "2960 Silver Ave",
      "state": "MD"
    },
    {
      "zip": "99999",
      "city": "Curry",
      "street_address": "2960 Silver Ave",
      "state": "PA"
    }
  ]
}
{
  "name": "Sam Q",
  "addresses": [ ]
}
{
  "name": "Sam R"
}

JSON数据集是否有FILLRECORD的替代方法?

我正在寻找一种可以在Redshift表中加载以上所有3条记录的实现或解决方法。

2 个答案:

答案 0 :(得分:1)

没有JSON的FILLRECORD等效项。 It is explicitly not supported in the documentation.

但是您有一个更基本的问题-第一条记录包含多个addresses的数组。 Redshift的COPY from JSON不允许您从嵌套数组创建多行。

解决此问题的最简单方法是使用define the files to be loaded as an external table并使用我们的nested data syntax将嵌入式数组扩展为完整的行。然后使用INSERT INTO将数据加载到最终表中。

DROP TABLE IF EXISTS spectrum.partial_json;
CREATE EXTERNAL TABLE spectrum.partial_json (
  name       VARCHAR(100),
  addresses  ARRAY<STRUCT<zip:INTEGER
                         ,city:VARCHAR(100)
                         ,street_address:VARCHAR(255)
                         ,state:VARCHAR(2)>>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://my-test-files/partial_json/'
;

INSERT INTO final_table 
SELECT ext.name
     , address.zip
     , address.city
     , address.street_address
     , address.state
FROM spectrum.partial_json ext
LEFT JOIN ext.addresses address ON true
;
--  name  |  zip  |     city      | street_address  | state
-- -------+-------+---------------+-----------------+-------
--  Sam P | 12345 | Silver Spring | 2960 Silver Ave | MD
--  Sam P | 99999 | Curry         | 2960 Silver Ave | PA
--  Sam Q |       |               |                 |
--  Sam R |       |               |                 |

注意:我对示例JSON进行了一些调整,以使其变得更简单。例如,您有未加密的对象作为我制作为纯字符串值的name的值。

答案 1 :(得分:0)

怎么样...

{
  "name": "Sam R"
  "address": ""
}