我的周期性运行进程使用"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
1条答案
按热度按时间dojqjjoe1#
以下2个设置不完全相同。
https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
https://spark.apache.org/docs/latest/configuration.html
对于spark,它控制是否在插入之前删除分区。
对于配置单元设置,这用于控制插入中的语法。在严格模式下,它至少需要一个静态分区,而在非严格模式下,所有分区都可以是动态的。