微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AWS Glue - 在 json 文件中具有不同架构的 DynamicFrame

如何解决AWS Glue - 在 json 文件中具有不同架构的 DynamicFrame

示例: 我在 glue 目录中有一个带有 DDL 的分区表:

CREATE EXTERNAL TABLE `test`(
  `id` int,`data` struct<a:string,b:string>)
PARTITIONED BY ( 
  `partition_0` string)
ROW FORMAT SERDE 
  'org.openx.data.jsonserde.JsonSerDe' 

S3 中的底层数据是具有不同架构的 json 文件,这意味着某些元素可能不存在于某些文件中,而存在于其他文件中。

在此示例中 partition_0='01' 包含具有所有元素的 json 文件

{"id": 1,"data": {"a": "value-a","b": "value-b"}}

partition_0='02' 中的文件不包含元素数据。b:

{"id": 1,"data": {"a": "value-a"}}

问题: 当我在 glue 中创建 DynamicFrame 时(我使用 Python),它的架构取决于我查询的数据。如果我包含来自 partition_0='01' 的数据,则所有元素都存在于架构中。

id_partition_predicate="partition_0 = '01'"
print("partition with 'b'")
glueContext.create_dynamic_frame.from_catalog(database = glue_source_database,table_name = "test",push_down_predicate = id_partition_predicate).printSchema()

partition with 'b'
root
|-- id: int
|-- data: struct
|    |-- a: string
|    |-- b: string
|-- partition_0: string
print("both partitions")
glueContext.create_dynamic_frame.from_catalog(database = glue_source_database,table_name = "test").printSchema()

both partitions
root
|-- id: int
|-- data: struct
|    |-- a: string
|    |-- b: string
|-- partition_0: string

如果我只查询来自 partition_0='02' 的数据,那么即使元素 data.b 存在于表定义中,它也不存在于 DynamicFrame 架构中。

print("partition without 'b'")
id_partition_predicate="partition_0 = '02'"
glueContext.create_dynamic_frame.from_catalog(database = glue_source_database,push_down_predicate = id_partition_predicate).printSchema()


partition without 'b'
root
|-- id: int
|-- data: struct
|    |-- a: string
|-- partition_0: string

问题:如何创建始终包含 glue 表架构中所有元素的 DynamicFrame 或 DataFrame?

提前致谢!

解决方法

想出了这个解决方案:

id_partition_predicate="partition_0 = '02'"
dyf = glueContext.create_dynamic_frame.from_catalog(database = glue_source_database,table_name = "test",push_down_predicate = id_partition_predicate)
dyf.printSchema()

df=dyf.toDF()
try:  
    df = df.withColumn("b",col("data").getItem("b"))
except:
    df = df.withColumn("b",lit(None).cast(StringType()))
df.show()

输出:

root
|-- id: int
|-- data: struct
|    |-- a: string
|-- partition_0: string

+---+---------+-----------+----+
| id|     data|partition_0|   b|
+---+---------+-----------+----+
|  1|[value-a]|         02|null|
+---+---------+-----------+----+

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。