我们如何覆盖分区数据集,但只覆盖我们要更改的分区?例如,重新计算上周的日常工作,并且只覆盖上周的数据.
默认的Spark行为是覆盖整个表,即使只写一些分区.
我遇到的问题是Hive表的架构在使用Spark 2.1.0和Hive 2.1.1的Mapr集群上的Spark和Hive之间不同步.
我需要尝试专门为托管表解决此问题,但可以使用非托管/外部表重现该问题.
saveAsTable一个数据帧保存到一个给定的表.mode("overwrite").parquet("path/to/table")覆盖数据之前保存表.我实际上是通过Spark和Hive外部的进程修改数据,但这会重现同样的问题.spark.catalog.refreshTable(...)刷新元spark.table(...).show().原始数据框和覆盖的数据框之间的任何列都将正确显示新数据,但不会显示仅在新表中的任何列.db_name = "test_39d3ec9"
table_name = "overwrite_existing"
table_location = "<spark.sql.warehouse.dir>/{}.db/{}".format(db_name, table_name)
qualified_table = "{}.{}".format(db_name, table_name)
spark.sql("CREATE DATABASE IF NOT EXISTS {}".format(db_name))
Run Code Online (Sandbox Code Playgroud)
另存为托管表
existing_df = spark.createDataFrame([(1, 2)])
existing_df.write.mode("overwrite").saveAsTable(table_name)
Run Code Online (Sandbox Code Playgroud)
请注意,使用以下内容保存为非托管表将产生相同的问题:
existing_df.write.mode("overwrite") \
.option("path", table_location) \
.saveAsTable(qualified_table)
Run Code Online (Sandbox Code Playgroud)
查看表的内容
spark.table(table_name).show()
+---+---+
| _1| _2|
+---+---+
| 1| 2|
+---+---+
Run Code Online (Sandbox Code Playgroud)
直接覆盖镶木地板文件
new_df = spark.createDataFrame([(3, 4, 5, 6)], ["_4", "_3", "_2", "_1"])
new_df.write.mode("overwrite").parquet(table_location)
Run Code Online (Sandbox Code Playgroud)
使用镶木地板阅读器查看内容,内容显示正确
spark.read.parquet(table_location).show()
+---+---+---+---+
| _4| _3| …Run Code Online (Sandbox Code Playgroud) 以下命令已成功将外部表转换为中的托管表Spark 2.0.0:
ALTER TABLE {table_name} SET TBLPROPERTIES(EXTERNAL=FLASE);
Run Code Online (Sandbox Code Playgroud)
但是,上面的命令失败Spark 2.2.0并显示以下错误:
查询错误:无法设置或更改保留的属性键:'EXTERNAL';
HIVE 中的外部表按年、月和日进行分区。
那么以下查询是否会从此查询中引用的特定分区的外部表中删除数据?:-
ALTER TABLE MyTable DROP IF EXISTS PARTITION(year=2016,month=7,day=11);
Run Code Online (Sandbox Code Playgroud)