我可以在插入现有字段时对Hive表进行分区吗?
我有一个10 GB的文件,其中包含日期字段和一小时的字段。我可以将此文件加载到表中,然后插入覆盖到另一个使用这些字段作为分区的分区表吗?会有类似以下的工作吗?
INSERT OVERWRITE TABLE tealeaf_event PARTITION(dt=evt.datestring,hour=evt.hour)
SELECT * FROM staging_event evt;
谢谢!
特拉维斯
答案 0 :(得分:12)
我只是碰到了这个尝试回答同样的问题,这很有帮助,但并不完全。简短的回答是肯定的,像问题中的查询会起作用,但语法不太正确。
假设您有三个使用以下语句创建的表:
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;
那应该这样做。
答案 1 :(得分:1)
也许已经回答了......但是,你可以完全按照你的说法去做。我做了很多次。显然,您的新表需要定义类似于原始表,但没有分区列,并且需要使用分区规范。另外,我不记得是否必须明确列出原始表中的列,或者asterik是否足够。
答案 2 :(得分:0)
我对此并不十分确定,但这样的事情可能会起作用
INSERT OVERWRITE TABLE tealeaf_event
SELECT col1 as tealeaf_col1, ..., datestring as ds;
答案 3 :(得分:-1)
没有。您将不得不删除该字段,或者至少重命名它。