spark - scala - 使用覆盖模式将数据帧保存到表中

Uda*_*gar 4 scala apache-spark

我想知道这里究竟是什么"覆盖".假设我在表"tb1"中有一个包含以下记录的表(对于表的错误表示感到抱歉)

司机vin制作模型

martin abc ford escape
john abd toyota camry
amy abe chevrolet malibu
carlos abf honda civic
Run Code Online (Sandbox Code Playgroud)

现在我有以下数据帧(mydf)具有相同的列但具有以下行/数据

martin abf toyota corolla
carlos abg nissan versa
Run Code Online (Sandbox Code Playgroud)

在使用覆盖模式将上述数据帧保存到"tb1"之后,数据帧是否会完全删除"tb1"的内容并写入mydf的数据(以上两个记录)?

但是,我希望覆盖模式仅覆盖列"driver"具有相同值的那些行.在这种情况下,"tb1"中有4条记录,mydf只会覆盖2条以上的记录,结果表格如下 -

司机vin制作模型

martin abf toyota corolla
john abd toyota camry
amy abe chevrolet malibu
carlos abg nissan versa
Run Code Online (Sandbox Code Playgroud)

我可以使用覆盖模式实现此功能吗?

mydf.write.mode(SaveMode.Overwrite).saveAsTable("tb1")
Run Code Online (Sandbox Code Playgroud)

Avi*_*rya 10

你的意思是在主键上合并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")
Run Code Online (Sandbox Code Playgroud)


Eri*_*jas 6

回答你的问题:

我可以使用覆盖模式实现此功能吗?

不,你不能。

Overwrite 函数的作用实际上是删除所有要填充的表并再次创建它,但现在使用您告诉它的新 DataFrame。

为了获得您想要的结果,您需要执行以下操作:

  • 将要“更新”的表信息保存到新的 DataFrame 中:

    val dfTable = hiveContext.read.table("table_tb1")

  • 在要更新的表的 DF (dfTable) 和包含新信息的 DF (mydf) 之间进行左连接,并交叉“PK”,在您的情况下,这将是驱动程序列。

在同一句话中,您过滤mydf("driver")列为null 的记录,即不匹配的记录,并且这些记录没有更新。

val newDf = dfTable.join(mydf, dfTable("driver") === mydf("driver"), "leftouter" ).filter(mydf("driver").isNull)
Run Code Online (Sandbox Code Playgroud)
  • 之后,截断表tb1并插入两个 DataFrame: newDFmydf DataFrame:

|

dfArchivo.write.mode(SaveMode.Append).insertInto("table_tb1")  /** Info with no changes */
mydf.write.mode(SaveMode.Append).insertInto("table_tb1") /** Info updated */
Run Code Online (Sandbox Code Playgroud)

这样,您就可以获得您正在寻找的结果。

问候。