Spark读取不同版本的Parquet文件

时间:2017-04-27 22:04:50

标签: apache-spark parquet versions

我使用Version1架构生成了超过一年的镶木地板文件。通过最近的架构更改,较新的镶木地板文件具有Version2架构额外列。

因此,当我从旧版本和新版本一起加载镶木地板文件并尝试过滤更改的列时,我得到一个例外。

我希望spark能够读取旧文件和新文件,并在列不存在的情况下填充空值。这是一个解决方法,当找不到列时spark会填充空值吗?

3 个答案:

答案 0 :(得分:1)

有两种方法可以尝试。

1.这样你可以使用地图转换,但不建议这样做,例如spark.read.parquet("mypath").map(e => val field =if (e.isNullAt(e.fieldIndex("field"))) null else e.getAs[String]("field"))

2.您可以使用mergeSchema选项的最佳方式,例如:

spark.read.option("mergeSchema", "true").parquet(xxx).as[MyClass]

REF:schema-merging

答案 1 :(得分:0)

假设您有一组想要阅读的文件:

  1. 查询集合中每个文件的模式,生成N组文件,每组文件包含具有相似模式的文件。
  2. 使用与每组中的架构兼容的过滤器对每组文件进行操作。
  3. 联合每个集合的过滤/操作结果(假设您的输出与每个文件架构的结果相同)

答案 2 :(得分:0)

SparkSQL本身支持镶木地板文件的模式合并。您可以在official documentation here

中阅读所有相关信息
  

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

     

由于模式合并是一项相对昂贵的操作,并且不是   在大多数情况下,我们必须从默认情况下将其关闭   1.5.0。您可以通过

启用它
  1.   

    在读取Parquet时将数据源选项mergeSchema设置为true   文件(如下面的例子所示)或

  2.   

    将全局SQL选项spark.sql.parquet.mergeSchema设置为true。