保存到镶木地板子分区
Saving to parquet subpartition
我有一个基于两个分区的目录结构,如下所示:
People
> surname=Doe
> name=John
> name=Joe
> surname=White
> name=Josh
> name=Julien
我正在阅读仅包含所有 Does 信息的镶木地板文件,因此我直接 指定 surname=Doe 作为我的 DataFrame 的输出目录。现在的问题是我正在尝试在写作时使用 partitionBy("name")
添加基于名称的分区。
df.write.partitionBy("name").parquet(outputDir)
(outputDir 包含 Doe 目录的路径)
这会导致如下错误:
Caused by: java.lang.AssertionError: assertion failed: Conflicting partition column names detected:
Partition column name list #0: surname, name
Partition column name list #1: surname
有什么解决方法吗?这可能是因为在姓氏目录中创建了 _SUCCESS
文件,这给 Spark 提供了错误的提示 - 当我删除 _SUCCESS
和 _metadata
文件时,Spark 能够毫无问题地读取所有内容。
我已经设法通过变通方法解决了它 - 我认为这不是一个好主意,但我禁用了创建额外的 _SUCCESS 和 _metadata 文件:
sc.hadoopConfiguration.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false")
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false")
这样 Spark 就不会对分区结构有任何愚蠢的想法。
另一个选项是保存到 "proper" 目录 - 人物和按姓氏和名字分区,但是你必须记住,唯一合理的选项是将 SaveMode
设置为 Append
并手动删除您希望被覆盖的目录(这 确实 容易出错):
df.write.mode(SaveMode.Append).partitionBy("surname","name").parquet("/People")
在这种情况下不要使用 owerwrite SaveMode - 这将删除所有姓氏目录。
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false")
这是相当明智的,如果您启用了摘要元数据,那么写入元数据文件可能会成为读写的 IO 瓶颈。
您的解决方案的替代方法可能是将 .mode("append") 添加到您的写入中,但将原始父目录作为目标,
df.write.mode("append").partitionBy("name").parquet("/People")
我有一个基于两个分区的目录结构,如下所示:
People
> surname=Doe
> name=John
> name=Joe
> surname=White
> name=Josh
> name=Julien
我正在阅读仅包含所有 Does 信息的镶木地板文件,因此我直接 指定 surname=Doe 作为我的 DataFrame 的输出目录。现在的问题是我正在尝试在写作时使用 partitionBy("name")
添加基于名称的分区。
df.write.partitionBy("name").parquet(outputDir)
(outputDir 包含 Doe 目录的路径)
这会导致如下错误:
Caused by: java.lang.AssertionError: assertion failed: Conflicting partition column names detected:
Partition column name list #0: surname, name
Partition column name list #1: surname
有什么解决方法吗?这可能是因为在姓氏目录中创建了 _SUCCESS
文件,这给 Spark 提供了错误的提示 - 当我删除 _SUCCESS
和 _metadata
文件时,Spark 能够毫无问题地读取所有内容。
我已经设法通过变通方法解决了它 - 我认为这不是一个好主意,但我禁用了创建额外的 _SUCCESS 和 _metadata 文件:
sc.hadoopConfiguration.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false")
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false")
这样 Spark 就不会对分区结构有任何愚蠢的想法。
另一个选项是保存到 "proper" 目录 - 人物和按姓氏和名字分区,但是你必须记住,唯一合理的选项是将 SaveMode
设置为 Append
并手动删除您希望被覆盖的目录(这 确实 容易出错):
df.write.mode(SaveMode.Append).partitionBy("surname","name").parquet("/People")
在这种情况下不要使用 owerwrite SaveMode - 这将删除所有姓氏目录。
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false")
这是相当明智的,如果您启用了摘要元数据,那么写入元数据文件可能会成为读写的 IO 瓶颈。
您的解决方案的替代方法可能是将 .mode("append") 添加到您的写入中,但将原始父目录作为目标,
df.write.mode("append").partitionBy("name").parquet("/People")