2016-03-22 94 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)