首页 > 解决方案 > 在 AWS Glue 中读取分区的 Avro 文件

问题描述

例如,我有一个存储桶,它在 Avro 中有大量数据以“蜂巢”样式分区

s3://my-bucket/year=2018/month=03/day=25/file-name.avro

我试图在 Glue 中访问这些数据:

val predicate = "year=2018 and month=03"
val opts = JsonOptions("""{ "paths": ["s3://my-bucket/"], "recurse": true }""")
val src = glueContext.getSource(connectionType = "s3"
                               , connectionOptions = opts
                               , pushDownPredicate = predicate
                               ).withFormat("avro")

但是这个表达式失败了,但有一个例外:

com.amazonaws.services.glue.util.NonFatalException: User's pushdown predicate: year=2018 and month=03 can not be resolved against partition columns: []

我尝试过这样的事情:

val predicate = "year=2018 and month=3"
val opts = JsonOptions("""{ "paths": ["s3://my-bucket/"], "recurse": true }""")
val src = glueContext.getSourceWithFormat(connectionType = "s3", format="avro", options = opts, pushDownPredicate = predicate)

但它根本不接受下推谓词:

error: unknown parameter name: pushDownPredicate

我也尝试添加

"partitionKeys": ["year", "month", "day"]

JsonOptions,也没有成功。

如何在没有爬虫的情况下在 Glue 中读取配置单元分区的 Avro 序列化数据?

标签: amazon-web-servicesaws-glue

解决方案


目前不可能使用下推谓词getSource()getSourceWithFormat()因为它在内部验证表达式中的字段是否实际上是分区。它从getCatalogSource()Glue Catalog 加载此信息并传递给验证器。因为getSource()并且getSourceWithFormat()不可能传递要用于验证的数据分区的自定义列表,因此不可能使用下推谓词。

作为一种解决方法,您可以生成包含数据分区的路径并将其getSourceWithFormat()通过options. 例如,如果你想加载数据,year=2018 and (month=03 or month=04)那么你的代码应该是这样的:

val paths = Array(
    "s3://bucket/data/year=2018/month=03",
    "s3://bucket/data/year=2018/month=04"
)

val source = glueContext.getSourceWithFormat(
  connectionType = "s3",
  format = "avro",
  options = JsonOptions(Map(
    "paths" -> paths,
    "recurse": true
))).getDynamicFrame()

请注意,sourceDynamicFrame 不包含分区列yearmonth因此您可能需要手动添加它们。


推荐阅读