如何在 spark scala 中覆盖特定的表分区

Posted

技术标签:

【中文标题】如何在 spark scala 中覆盖特定的表分区【英文标题】:How to overwrite a specific table partition in spark scala 【发布时间】:2021-05-16 23:04:26 【问题描述】:

我有一个按日期分区的表,我试图覆盖一个特定的分区,但是 当我尝试下面的代码时,它会覆盖整个表格

query.write.partitionBy("date").mode(SaveMode.Overwrite).format("orc").insertInto(mytableName)

但我想通过提供分区列名称及其值来覆盖特定分区 喜欢partitionBy(date='20-01-2021');

有没有办法覆盖特定的分区?

【问题讨论】:

您应该使用合并语句并进行分区修剪以进行更新插入或动态覆盖任何分区.. 【参考方案1】:

您可以指定要覆盖的分区的完整路径。在这种情况下,您不需要执行 query.write.partitionBy("date") 并且您需要在编写之前删除 date 列:

query.drop("date")
  .write
  .mode("overwrite")
  .format("orc")
  .save("/data/mytableName/date=20-01-2021")

【讨论】:

感谢您的回复。但是有没有办法不给出分区列的路径。?我正在尝试日期和表格值将变化并作为变量传递的情况 @M_Still_Learning 非,你不能。您必须重写所有表或像上面那样直接写入给定分区。您可以使用变量格式化路径。 我试图覆盖到表路径但插入零记录。你能帮到你吗? @M_Still_Learning 有什么问题?你有任何错误吗?【参考方案2】:

尝试这种方法并适应您的具体情况:

需要在 hive 或 spark 中设置表。

遵循这种动态的方法:

spark.conf.set("spark.sql.sources.partitionOverwriteMode", "dynamic")
import org.apache.spark.sql.types._

val df = spark.range(9).map(x => (x, (x + 100) % 3)).toDF("c1", "c2")
df.repartition($"c2")
  .write
  .partitionBy("c2")
  .mode("overwrite").saveAsTable("tabX")

更新一个分区 - 人为,在设置后以这种方式

val df2 = spark.range(1).map(x => (x, (x + 100) % 3)).toDF("c1", "c2")
df2.repartition($"c2")
   .write
   .mode("overwrite").insertInto("tabX")

查看效果并根据您的具体情况进行调整。

// from 9 -> 7 entries, pls run
val df3 = spark.table("tabX")
df3.show(false)

【讨论】:

谢谢。但我试图覆盖特定分区列值而不是分区列。我能够插入特定列而不是如上所述的列值。你能帮忙吗

以上是关于如何在 spark scala 中覆盖特定的表分区的主要内容,如果未能解决你的问题,请参考以下文章

在 spark 和 scala 中,如何将数据框转换或映射到特定列信息?

使用 Glue 连接和 spark scala 覆盖 Mysql 表

在scala中使用spark sql解决特定需求

Spark 是不是支持插入覆盖静态分区?

scala-spark实现重分区和打印各个分区的data

如何在scala spark中将数据框的特定列与另一个列连接[重复]