2017-09-28 83 views
1

我想知道這裏「覆蓋」到底是什麼。比方說,我有表「TB1」下記錄的表(抱歉表的糟糕表現)spark-scala - 將數據框保存到覆蓋模式下的表

駕駛車輛品牌型號

martin abc ford escape 
john abd toyota camry 
amy abe chevrolet malibu 
carlos abf honda civic 

現在我有以下的數據框(myDF上)與相同列但與follwing行/數據

martin abf toyota corolla 
carlos abg nissan versa 

保存上述數據幀的「TB1的」與覆蓋模式之後,將所述數據幀完全刪除的「TB1」的內容和寫入是myDF的數據(上面的兩個記錄)?

但是,我想覆蓋模式只覆蓋那些列「驅動程序」具有相同值的行。在這種情況下,4個記錄在「TB1」,是myDF將只覆蓋上述2條記錄,所得表將如下─

駕駛車輛品牌型號

martin abf toyota corolla 
john abd toyota camry 
amy abe chevrolet malibu 
carlos abg nissan versa 

我能實現這個功能使用覆蓋模式?

mydf.write.mode(SaveMode.Overwrite).saveAsTable("tb1") 

回答

2

你的意思是在主鍵上合併2個數據幀。您想要合併兩個數據框,並用新行替換舊行並追加多餘的行(如果存在)。

這不能通過SaveMode.Overwrite或SaveMode.append來實現。

爲此,您需要在主鍵上實現2個數據幀的合併功能。

像這樣的事情

parentDF = // actual dataframe 
deltaDF = // new delta to be merged 


val updateDF = spark.sql("select parentDF.* from parentDF join deltaDF on parentDF.id = deltaDF.id") 
val totalDF = parentDF.except(updateDF).union(deltaDF) 
totalDF.write.mode(SaveMode.Overwrite).saveAsTable("tb1") 
2

回答你的問題:

我可以實現使用覆蓋模式,此功能?

不,你不能。

覆蓋的功能實際上是刪除所有要填充的表格並重新創建,但現在使用您正在告訴的新數據框。

爲了得到你想要的結果,你會做以下幾點:

  • 保存您的表的信息,以「更新」到一個新的數據幀:

    VAL dfTable = hiveContext.read。表( 「table_tb1」)

  • 做一個左連接表的DF之間更新(dfTable),並 的DF(myDF上)與你的新的信息,你的 「PK」 跨越,這 在你的情況下,將是驅動程序列。

在同一個句子,您篩選是不匹配的,並沒有對這些部分上沒有更新的人的記錄,其中是myDF(「驅動程序」)爲空

val newDf = dfTable.join(mydf, dfTable("driver") === mydf("driver"), "leftouter").filter(mydf("driver").isNull) 
  • 之後,截斷你的表TB1並插入兩個DataFrames:在 newDF是myDF DataFrames:

|

dfArchivo.write.mode(SaveMode.Append).insertInto("table_tb1") /** Info with no changes */ 
mydf.write.mode(SaveMode.Append).insertInto("table_tb1") /** Info updated */ 

以這種方式,你可以得到你正在尋找的結果。

問候。