首页 > 解决方案 > 用于提取 JSON 数组值的 AWS Glue 分类器

问题描述

我在 S3 中有文件,每行结构都带有内联 JSON:

{ "resources": [{"resourceType":"A","id":"A",...},{...}] }

如果我在它上面运行胶水,我会得到“资源:数组”作为顶级元素。但是,我希望检查数组的元素并将其用作顶级表元素。每个资源数组的所有元素都将具有相同的架构。所以我期待

resourceType: string
id: string
....

理论上,自定义 JSON 分类器应该处理这个问题:

$.resources[*]

但是,路径没有被拾取。所以我仍然将资源:数组作为顶级元素。

我现在可以运行一些预处理来自己提取数组元素并逐行编写它们。但是,我想了解为什么我的路径不起作用。

更新 1:

这可能是我不理解的 JSON (通过 JAVA Jackson 生成的有效 JSON)。如果我删除具有资源属性的外部对象并将结构更改为

[{"resourceType":"A","id":"A",...},{...}]

分类器$[*]应该选择子对象。但我仍然得到array:arra y 作为顶级元素。

更新 2:

它确实是一个格式问题。如果我将 JSON 文件更改为

[
  {"resourceType":"A","id":"A",...},{...}
]

$[*]开始工作。

更新 3:

然而,它并没有解决$.resources[*]重新格式化的问题

{
    "resources": [
        {"resourceType":"A","id":"A",...},{...}
    ]
}

更新 4:

如果我获取我的文件并通过 Intellij 重新格式化运行它,从而生成一个 JSON 对象,其中所有嵌套元素都有换行符,它也开始使用$.resources[*]. 基本上,就像在 UPDATE 3 中一样,只是应用了结构。

{
    "resources": [
        {
          "resourceType":"A",
          "id":"A"
        },
        {
          ...
        }
    ]
}

困扰我的是,关于结构的要求我仍然不清楚,因为 UPDATE 2 有效,但不是 UPDATE 3。我在文档中也找不到关于 JSON 结构的正式要求。

从这个意义上说,我想我已经得出了自己的问题的结论,但系统学仍然有点不清楚。

标签: jsonamazon-web-servicesetlaws-glue

解决方案


在这里总结一下:

该问题与 Glue 的记录不明确的 JSON 格式要求有关。

标准化通过json.dumps(my_json, separators=(',',':'))生成适用于我的用例的紧凑 JSON。

我现在通过 lambda 对内容进行了标准化。

Lambda 代码作为对任何人有帮助的参考:

    s3 = boto3.client('s3')

    paginator = s3.get_paginator('list_objects_v2')

    pages = paginator.paginate(Bucket=my_bucket)
    
    for page in pages:
        try:
            contents = page["Contents"]
        except KeyError:
            break

        for obj in contents:
            key = obj["Key"]
            obj = s3.get_object(Bucket=my_bucket, Key=key)
            j = json.loads(obj['Body'].read().decode('utf-8'))
            
            new_json = json.dumps(j, separators=(',',':'))
                
            target = 'nrmlzd/' + key
                
            s3.put_object(
                Body=new_json,
                Bucket=my_bucket,
                Key= target
            )

推荐阅读