我刚刚遇到了这个问题,试图回答同样的问题,它很有帮助,但还不够完整。简短的回答是肯定的,类似问题中的查询会起作用,但语法不太正确。
假设您有三个使用以下语句创建的表:
CREATE TABLE staging_unpartitioned (datestring string, hour int, a int, b int);
CREATE TABLE staging_partitioned (a int, b int)
PARTITIONED BY (datestring string, hour int);
CREATE TABLE production_partitioned (a int, b int)
PARTITIONED BY (dt string, hour int);
列a 和b 只是一些示例列。 dt 和 hour 是我们想要在它到达生产表后对其进行分区的值。将暂存数据从 staging_unpartitioned 和 staging_partitioned 移至生产环境看起来完全一样。
INSERT OVERWRITE TABLE production_partitioned PARTITION (dt, hour)
SELECT a, b, datestring, hour FROM staging_unpartitioned;
INSERT OVERWRITE TABLE production_partitioned PARTITION (dt, hour)
SELECT a, b, datestring, hour FROM staging_partitioned;
这使用了一个称为动态分区的过程,您可以阅读有关here 的信息。需要注意的重要一点是,哪些列与哪些分区相关联是由 SELECT 顺序决定的。所有动态分区都必须按顺序最后选择。
当您尝试运行上面的代码时,很有可能会因为您设置的属性而遇到错误。首先,如果您禁用了动态分区,它将无法工作,因此请确保:
set hive.exec.dynamic.partition=true;
如果您没有在动态分区之前至少在一个静态分区上进行分区,那么您可能会遇到错误。当您打算用动态分区覆盖其子分区时,此限制将避免您意外删除根分区。以我的经验,这种行为从来没有帮助过,而且经常很烦人,但你的里程可能会有所不同。无论如何,它很容易改变:
set hive.exec.dynamic.partition.mode=nonstrict;
应该这样做。