首页 > 解决方案 > 配置单元中的动态分区表不更新最近的分区

问题描述

我在 gcs 存储桶中有一个文件夹,其文件夹结构为

Xyz/Abc/dt=03-12-2021/file_03-12-2021.csv
Xyz/Abc/dt=04-12-2021/file_04-12-2021.csv

我正在尝试通过执行以下查询在文件夹顶部创建一个动态分区表

Set hive.exec.dynamic.partition.mode=nonstrict
Set hive.exec.dynamic.partition=true


Create table tabName (sno int, city string, address string) partitioned by (dt string);

Create table tabStg (sno int, city string, address string, dt string) row format delimited fields terminated by ‘|’ stored as textfile location ‘gcs://Xyz/Abc’;

Insert overwrite table tabName partition(dt) select sno,city,address,dt from tabStg;

执行插入语句后,我收到一条消息

将数据加载到表 db.tabName (dt=null)

如果我在show partitions tabName;获得所有分区时进行查询。但是,如果在 gcs 存储桶中为新日期创建了一个新文件夹,则分区表无法识别该文件夹。

任何建议为什么会发生这种情况。我错过了什么吗

标签: hivehiveqlpartitioninghive-partitions

解决方案


Hive 中没有“动态分区表”这样的东西。表可以分区或不分区。动态分区模式 - 是在 INSERT 期间加载数据的方式 - 可以指定单个静态分区,或者可以从选择中动态加载分区。

动态分区加载示例:

Insert overwrite table tabName partition(dt) --partition is not specified 
select sno,city,address,dt from tabStg where...; --will be loaded dynamically

静态分区负载示例:

Insert overwrite table tabName partition(dt='2021-03-01') --static partition specified
select sno,city,address from tabStg where dt='2021-03-01'; --take care about correct data loaded

在最后一个查询中指定静态分区:partition(dt='2021-03-01')注意,在这种情况下分区列不存在于选择中。如果不在 WHERE 中过滤,您可以在同一分区中加载一些其他日期。

两者之间的区别在于,在动态加载的情况下,您可以重写所有现有分区并加载新的分区,在静态加载的情况下,您只能加载分区规范中指定的分区。如果未启用动态模式,第一次查询将失败,这是一种防止无意覆盖分区的保护,仅此而已。

如果新的分区文件夹出现在表文件夹中,则不会自动发生任何事情,如果尚未使用 MSCK REPAIR 或 ALTER TABLE 完成,则需要在 tabStg 表中创建分区,然后使用静态加载或动态加载重复加载到第二个表 tabName。

除此之外,Hive 能够自动管理分区:如果新的分区文件夹被第三方工具加载到文件系统的表文件夹中,则添加分区。阅读更多:自动管理分区- 如果此功能在您的 Hive 中有效,您无需在源表中手动添加分区(如果您有此功能,则无需 REPAIR 表或 ATER)。但无论如何,应该像以前一样将数据加载到第二个表中。


推荐阅读