在 Spark 的 saveAsTable 上

Posted

技术标签:

【中文标题】在 Spark 的 saveAsTable 上【英文标题】:On saveAsTable from Spark 【发布时间】:2018-07-17 22:08:51 【问题描述】:

我们正在尝试从 SPARK 写入 HIVE 表,并且我们正在使用 saveAsTable 函数。我想知道每次 saveAsTable 是否删除并重新创建配置单元表?如果是这样,那么是否有任何其他可能的 spark 函数实际上只是截断并加载表,而不是删除并重新创建。

【问题讨论】:

【参考方案1】:

这取决于您指定的 .mode 值

覆盖 --> 然后 spark 先删除表,然后重新创建表

追加 --> 向表中插入新数据

1.如果存在则删除/如果不存在则创建 default.spark1 拼花格式的表

>>> df.write.mode("overwrite").saveAsTable("default.spark1")

2.如果存在则删除/如果不存在则创建 default.spark1 orc 格式的表

>>> df.write.format("orc").mode("overwrite").saveAsTable("default.spark1")

3.将新数据追加到表中的现有数据(不删除/重新创建表)

>>> df.write.format("orc").mode("append").saveAsTable("default.spark1")

使用 Spark 实现截断和加载:

方法一:-

您可以将您的数据框注册为临时表,然后执行插入覆盖语句以覆盖目标表

>>> df.registerTempTable("temp") --registering df as temptable
>>> spark.sql("insert overwrite table default.spark1 select * from temp") --overwriting the target table.

此方法也适用于内部/外部表。

方法二:-

对于内部表,我们可以先截断表,然后将数据附加到表中,通过这种方式,我们不会重新创建表,而只是将数据附加到表中。

>>> spark.sql("truncate table default.spark1")
>>> df.write.format("orc").mode("append").saveAsTable("default.spark1")

此方法仅适用于内部表。

即使是外部表,我们也可以通过更改表属性来做一些变通方法来截断表。

假设 default.spark1 表是外部表并且

--change external table to internal table
>>> saprk.sql("alter table default.spark1 set tblproperties('EXTERNAL'='FALSE')")
--once the table is internal then we can run truncate table statement
>>> spark.sql("truncate table default.spark1")
--change back the table as External table again
>>> spark.sql("alter table default.spark1 set tblproperties('EXTERNAL'='TRUE')")
--then append data to the table
>>> df.write.format("orc").mode("append").saveAsTable("default.spark1")

【讨论】:

【参考方案2】:

您也可以使用insertInto("table"),它不会重新创建表

saveAsTable 的主要区别在于 insertInto 期望表已经存在并且基于列的顺序而不是名称。

【讨论】:

以上是关于在 Spark 的 saveAsTable 上的主要内容,如果未能解决你的问题,请参考以下文章

Spark:可以使用 DataFrame.saveAsTable 或 DataFrameWriter.options 传递哪些选项?

调用 saveAsTable 时出现 org.apache.spark.sql.AnalysisException

Spark 数据框 saveAsTable 正在使用单个任务

Spark SaveAsTable 元数据更新慢

Spark 3.0 - 使用 .save() 或 .saveAsTable() 保存时的读取性能

使用 saveAsTable 将 parquet 数据写入 S3 未完成