问题描述
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,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 存储桶中为新日期创建了一个新文件夹,则分区表将无法识别。
任何建议为什么会发生这种情况。 我是不是错过了什么
解决方法
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,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 能够自动管理分区:如果新的分区文件夹被第三个工具加载到文件系统的表文件夹中,则添加分区。阅读更多:Manage partitions automatically - 如果此功能在您的 Hive 中有效,则无需在源表中手动添加分区(如果您有此功能,则无需 REPAIR 表或 ATER)。但无论如何,将数据加载到第二个表应该像以前一样完成。