如何使用 Spark 执行插入覆盖?

cod*_*rer 2 scala apache-spark apache-spark-sql spark-dataframe

我正在尝试将我们的 ETL Hive 脚本之一转换为 Spark,其中 Hive ETL 脚本维护一个表,在新同步之前每天晚上需要删除部分数据。Hive ETL 使用插入覆盖将主表删除超过 3 天的数据。基本上创建一个临时表,其中的数据不超过三天,然后覆盖主表。

使用 Spark(使用 Scala)时,我不断收到此错误,无法写入相同的源。这是我的代码:

spark.sql ("Select * from mytbl_hive where dt > date_sub(current_date, 3)").registerTempTable("tmp_mytbl")

val mytbl = sqlContext.table("tmp_mytbl")
mytbl.write.mode("overwrite").saveTableAs("tmp_mytbl")

//writing back to Hive ...

mytbl.write.mode("overwrite").insertInto("mytbl_hive")
Run Code Online (Sandbox Code Playgroud)

我收到无法写入正在读取的表的错误。

有谁知道这样做的更好方法?

小智 5

你不能。正如您所了解的,Spark 明确禁止覆盖用作查询源的表。虽然根据技术细节存在一些变通方法,但并不可靠,应避免使用。

反而:

  • 将数据写入临时表。
  • 放下旧桌子。
  • 重命名临时表。

Hive ETL 使用插入覆盖将主表删除超过 3 天的数据。

按日期对数据进行分区,然后删除分区,甚至不查看数据,这可能是一个更好的主意。