spark 2.3.1 insertin删除字段的值并将其更改为null

时间:2019-01-02 21:32:45

标签: scala apache-spark

我只是将我的Spark集群从2.2.1升级到2.3.1,以便享受覆盖特定分区的功能。 see link

但是.... 由于某种原因,在进行测试时,我得到了一个非常奇怪的行为,请参见代码:

import org.apache.spark.SparkConf
import org.apache.spark.sql.{SaveMode, SparkSession}
case class MyRow(partitionField: Int, someId: Int, someText: String)
object ExampleForStack2 extends App{
  val sparkConf = new SparkConf()
  sparkConf.set("spark.sql.sources.partitionOverwriteMode","dynamic")
  sparkConf.setMaster(s"local[2]")
  val spark = SparkSession.builder().config(sparkConf).getOrCreate()
  val list1 = List(
    MyRow(1, 1, "someText")
      ,MyRow(2, 2, "someText2")
  )
  val list2 = List(
    MyRow(1, 1, "someText modified")
    ,MyRow(3, 3, "someText3")
  )
  val df = spark.createDataFrame(list1)
  val df2 = spark.createDataFrame(list2)

  df2.show(false)
  df.write.partitionBy("partitionField").option("path","/tmp/tables/").saveAsTable("my_table")
  df2.write.mode(SaveMode.Overwrite).insertInto("my_table")
  spark.sql("select * from my_table").show(false)
}

并输出:

+--------------+------+-----------------+
|partitionField|someId|someText         |
+--------------+------+-----------------+
|1             |1     |someText modified|
|3             |3     |someText3        |
+--------------+------+-----------------+

+------+---------+--------------+
|someId|someText |partitionField|
+------+---------+--------------+
|2     |someText2|2             |
|1     |someText |1             |
|3     |3        |null          |
|1     |1        |null          |
+------+---------+--------------+

为什么我得到这些空值? 似乎田野被感动了吗?但为什么?

谢谢

1 个答案:

答案 0 :(得分:0)

确定找到它,插入到基于字段的位置。参见documentation

  

与saveAsTable不同,insertInto忽略列名称,仅使用基于位置的分辨率。例如:

scala> Seq((1, 2)).toDF("i", "j").write.mode("overwrite").saveAsTable("t1")
scala> Seq((3, 4)).toDF("j", "i").write.insertInto("t1")
scala> Seq((5, 6)).toDF("a", "b").write.insertInto("t1")
scala> sql("select * from t1").show
+---+---+
|  i|  j|
+---+---+
|  5|  6|
|  3|  4|
|  1|  2|
+---+---+
  

由于它将数据插入到现有表中,因此格式或选项将   被忽略。

此外,我正在使用动态分区,该分区应该显示为最后一个字段。因此,解决方案是将动态分区移动到数据帧的末尾,这对我而言意味着:

df2.select("someId", "someText","partitionField").write.mode(SaveMode.Overwrite).insertInto("my_table")