2016-03-22 29 views
10

去除分配列我分区的数据帧如下:防止DataFrame.partitionBy()从模式

df.write.partitionBy("type", "category").parquet(config.outpath) 

的代码给出了预期的结果(即,通过&类型类别划分的数据)。但是,“类型”和“类别”列将从数据/模式中删除。有没有办法来防止这种行为?

+0

是不是一个问题?所有需要的数据仍然编码在目录结构中,因此不会丢失数据。如果你想要一个每个文件的值,你可以尝试'df.repartition(“type”,“category”)。write(...)'但你不会得到好的结构。 – zero323

+0

@ zero323:是的,我同意没有数据丢失。但是,对于某些使用情况,恢复用于分区的列是不平凡的。例如,如果我想在猪中加载数据,我将如何恢复类型和类别列? – Michael

+0

有段时间没有用过猪。 ParquetLoader不能理解开箱即用的结构吗? – zero323

回答

8

我可以想到一个解决方法,这是相当蹩脚的,但工程。

import spark.implicits._ 

val duplicated = df.withColumn("_type", $"type").withColumn("_category", $"category") 
duplicated.write.partitionBy("_type", "_category").parquet(config.outpath) 

我,希望有人会比我有更好的回答或解释回答这个问题(如果OP已经找到了更好的解决方案),但是,因为我有同样的问题。

+1

其实对我来说看起来不蹩脚。似乎是'partitionBy()'行为的最佳方法。 – Michael

1

一般来说,伊万的答案是一个很好的答案。但...

如果您严格阅读和书写火花,您可以在读取数据时使用basePath选项。

https://spark.apache.org/docs/2.2.0/sql-programming-guide.html#partition-discovery

通过传递路径/到/表要么SparkSession.read.parquet或SparkSession.read.load,火花SQL将自动提取的路径中的划分信息。

例子:

 val dataset = spark 
     .read 
     .format("parquet") 
     .option("basePath", hdfsInputBasePath) 
     .load(hdfsInputPath)