【发布时间】:2013-09-06 22:32:19
【问题描述】:
我有一个按日期分区的 Hive 表。我希望能够选择性地覆盖过去 'n' 天的分区(或自定义分区列表)。
有没有办法在不为每个分区编写“INSERT OVERWRITE DIRECTORY”语句的情况下做到这一点?
非常感谢任何帮助。
【问题讨论】:
我有一个按日期分区的 Hive 表。我希望能够选择性地覆盖过去 'n' 天的分区(或自定义分区列表)。
有没有办法在不为每个分区编写“INSERT OVERWRITE DIRECTORY”语句的情况下做到这一点?
非常感谢任何帮助。
【问题讨论】:
Hive 支持动态分区,因此您可以构建一个查询,其中分区只是源字段之一。
INSERT OVERWRITE TABLE dst partition (dt)
SELECT col0, col1, ... coln, dt from src where ...
where 子句可以指定要覆盖的 dt 值。
只需在源列表中最后包含分区字段(在本例中为 dt),如果 dt 字段已经是源的一部分,您甚至可以使用 SELECT *, dt 甚至 SELECT *,my_udf(dt) as dt 等
默认情况下,Hive 至少希望指定的分区之一是静态的,但您可以允许它为 nonstrict;所以对于上面的查询,可以在运行前进行如下设置:
set hive.exec.dynamic.partition.mode=nonstrict;
【讨论】:
SELECT *, dt 它抱怨我要插入更多列。这是有道理的,因为dt 也是* 的一部分。如果我这样做SELECT col0, col1, ... coln, dt from src where 它会抱怨Partition spec {dt=, DT=12} contains non-partition columns; 知道吗?似乎喜欢在分区列中发布案例,但我都尝试了
试试这个。这将从 * 中排除 dt,然后添加 dt 将根据需要设置顺序:
SET hive.support.quoted.identifiers=none;
INSERT OVERWRITE TABLE dst partition (dt)
SELECT `(dt)?+.+`, dt from tableName;
【讨论】: