为什么在胶水 pyspark ETL 作业中无法添加到镶木地板表中的新列?

rob*_*oby 6 parquet pyspark aws-glue

我们一直在探索使用 Glue 将一些 JSON 数据转换为 parquet。我们尝试过的一个场景是向镶木地板表添加一列。所以分区 1 有 [A] 列,分区 2 有 [A,B] 列。然后我们想编写更多的 Glue ETL 作业来聚合 parquet 表,但新列不可用。使用glue_context.create_dynamic_frame.from_catalog加载动态帧我们的新列从来没有在架构。

我们为我们的表格爬虫尝试了几种配置。所有分区使用单一架构,s3 路径使用单一架构,每个分区使用架构。我们总是可以看到 Glue 表数据中的新列,但如果我们使用 pyspark 从 Glue 作业中查询它,它总是为空。当我们下载一些样本并且可以通过 Athena 查询时,该列位于镶木地板中。

为什么 pyspark 无法使用新列?

rob*_*oby 9

结果证明这是一个火花配置问题。从火花文档

与 Protocol Buffer、Avro 和 Thrift 一样,Parquet 也支持模式演化。用户可以从一个简单的架构开始,然后根据需要逐渐向架构添加更多列。这样,用户最终可能会得到多个具有不同但相互兼容的模式的 Parquet 文件。Parquet 数据源现在能够自动检测这种情况并合并所有这些文件的模式。

由于模式合并是一项相对昂贵的操作,并且在大多数情况下不是必需的,因此我们从 1.5.0 开始默认关闭它。您可以通过以下方式启用它

  1. 读取 Parquet 文件时将数据源选项 mergeSchema 设置为 true(如下例所示),或
  2. 将全局 SQL 选项 spark.sql.parquet.mergeSchema 设置为 true。

我们可以通过两种方式启用模式合并。

  1. 在 spark 会话中设置选项 spark.conf.set("spark.sql.parquet.mergeSchema", "true")
  2. 在加载动态框架时设置mergeSchema为 true additional_options
source = glueContext.create_dynamic_frame.from_catalog(
   database="db",
   table_name="table",
   additional_options={"mergeSchema": "true"}
)
Run Code Online (Sandbox Code Playgroud)

之后,新列在框架的架构中可用。

  • 多谢。这应该在动态框架文档中 (3认同)