【问题标题】:Redshift COPY using JSONPath for missing array/fieldsRedshift COPY 使用 JSONPath 处理缺失的数组/字段
【发布时间】:2019-05-15 01:49:27
【问题描述】:

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

查询:

从 's3://mybucket/address.json' 复制地址
凭证'aws_access_key_id=XXXXXXX;aws_secret_access_key=XXXXXXX' 最大错误为 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 条记录的实现或解决方法。

【问题讨论】:

  • 您的address_jsonpath.json 文件内容对于提供答案非常重要。
  • @RedBoy 包含了 jsonpath 文件。
  • 我稍微调整了您的示例 JSON 以使其更简单。例如,您将未键入的对象作为 name 的值,我将其转换为纯字符串值。

标签: amazon-redshift jsonpath


【解决方案1】:

对于来自 JSON 的 COPY,没有 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 的值,我将其转换为纯字符串值。

【讨论】:

    【解决方案2】:

    怎么样...

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

    【讨论】:

    • 不鼓励使用纯代码的答案。请解释您的答案为何以及如何解决问题。
    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多