HDFS 使用saveAsTable创建的表的行为与使用spark.sql创建的表不同(“CREATE TABLE....")

juzqafwq  于 2023-01-22  发布在  HDFS
关注(0)|答案(1)|浏览(295)

我的周期性运行进程使用"spark.sql.sources.partitionOverwriteMode" = "dynamic"配置将数据写入 parquet 文件上的表,代码如下:

if (!tableExists) {
  df.write
    .mode("overwrite")
    .partitionBy("partitionCol")
    .format("parquet")
    .saveAsTable("tablename")
}
else {
  df.write
    .format("parquet")
    .mode("overwrite")
    .insertInto("table")
}

如果表不存在并且是在第一个子句中创建的,那么它可以正常工作,并且在下一次运行时,如果表确实存在并且else子句运行,那么它可以按预期工作。
然而,当我通过配置单元会话或使用spark.sql("CREATE TABLE...")在现有的 parquet 文件上创建表,然后运行进程时,它无法写入,并显示错误:

org.apache.spark.SparkException: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict

将此配置添加到spark conf解决了这个问题,但我不明白为什么在通过命令创建表时需要此配置,而在使用saveAsTable创建表时不需要此配置。
另外,我不明白这个配置与spark有什么关系。从我所读到的内容来看,这里的静态分区意味着我们直接指定要写入的分区,而不是指定要分区的列。在spark中是否有可能进行这样的插入(与HiveQL相反)?
Spark 2.4、Hadoop 3.1

dojqjjoe

dojqjjoe1#

以下2个设置不完全相同。

hive.exec.dynamic.partition.mode

https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties

spark.sql.sources.partitionOverwriteMode

https://spark.apache.org/docs/latest/configuration.html
对于spark,它控制是否在插入之前删除分区。
对于配置单元设置,这用于控制插入中的语法。在严格模式下,它至少需要一个静态分区,而在非严格模式下,所有分区都可以是动态的。

相关问题