2015-09-29 67 views
10

我有一個目錄結構基於兩個分區,就像這樣:保存到鑲子分區

People 
    > surname=Doe 
     > name=John 
     > name=Joe 
    > surname=White 
     > name=Josh 
     > name=Julien 

我讀拼花文件的信息只有所有呢,因此我直接指定姓= Doe的作爲我的DataFrame的輸出目錄。現在的問題是我試圖在編寫時添加partitionBy("name")的基於名稱的分區。

df.write.partitionBy("name").parquet(outputDir) 

(outputDir包含哆目錄的路徑)

這將導致一個錯誤象下面這樣:

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 

任何提示,該如何解決呢?這可能是因爲在surname目錄中創建了_SUCCESS文件,該文件給Spark提供了錯誤提示 - 當我刪除_SUCCESS_metadata文件時,Spark能夠無任何問題地讀取所有文件。

回答

7

我設法用一種變通方法來解決這個問題 - 我不認爲這是一個好主意,但我禁用創造更多_SUCCESS和_metadata文件有:

sc.hadoopConfiguration.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false") 
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

這樣星火不會得到關於分區結構的任何愚蠢的想法。

另一個選擇是保存到「正確的」目錄 - 人員和分區的姓氏和名稱,但是你必須記住,唯一的理智選擇是設置SaveModeAppend並手動刪除你期望的目錄覆蓋(這是真的容易出錯):

df.write.mode(SaveMode.Append).partitionBy("surname","name").parquet("/People") 

不要在這種情況下使用owerwrite SaveMode - 這將刪除所有姓directores的。

+0

因爲沒有人別的貼和我的賞金到期,我接受這個解決方案是目前唯一已知的解決方案。 – Niemand

+0

這適用於Spark 1.6.3'sc._jsc.hadoopConfiguration()。set(「mapreduce.fileoutputcommitter.marksuccessfuljobs」,「false」) sc._jsc.hadoopConfiguration()。set(「parquet.enable.summary -metadata「,」false「)' – Vezir

2
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

是相當明智的,如果你啓用了,然後寫元數據文件可以成爲一個IO瓶頸上讀取和寫入總結的元數據。

到解決方案中的另一種方法可能是添加一個.mode(「追加」)添加到您寫的,但與作爲目標的原始父目錄,

df.write.mode("append").partitionBy("name").parquet("/People") 
+0

append的問題是我將不得不手動刪除數據,這在我的情況下會很麻煩。 – Niemand

+0

是的,但是然後刪除Spark中的文件分區至多是最基本的... –