【发布时间】:2021-04-30 01:08:08
【问题描述】:
我需要从已分区的 Hive 表中删除特定行。这些要删除的行符合某些条件,因此不能为了这样做而删除整个分区。假设表Table 有三列:partner、date 和source_key,并由date 和source_key 分区。
已知不支持删除或更新 hive (See How to delete and update a record in Hive) 中的特定记录集的操作。
在this solution 之后,我成功执行了以下查询,以便保留仅匹配某些给定条件的记录,例如:属于date 的某个给定范围,具有source_key='heaven' 和专栏partner<>'angel'...
创建表Table的临时空副本。
CREATE TABLE IF NOT EXISTS tmpTable LIKE Table;
用当前行填充它。
INSERT OVERWRITE TABLE tmpTable
PARTITION (date,source_key)
SELECT * FROM Table
WHERE
date >= '2020-05-01' AND date < '2020-11-30' AND
source_key = 'heaven';
删除目标分区。
ALTER TABLE Table DROP IF EXISTS
PARTITION (source_key = 'heaven' , date >= '2020-05-01' , date < '2020-11-30' );
将已编辑的分区插入到目标表中。 (由于语法错误,无法插入 OVERWRITE)
INSERT INTO Table
PARTITION (source_key,date)
SELECT * FROM tmpTable
WHERE
partner <> 'angel';
删除临时表。
DROP TABLE IF EXISTS tmpTable;
查询运行良好。因为表 Table 是托管的,所以当分区被删除时,hdfs 文件应该被删除,但是有些地方是错误的(可能在最后一个 INSERT INTO 语句中),因为在执行所有这些查询之后目标表 Table 保持在给定的日期范围内所有带有partner = 'angel' 和带有 的记录基本上保持不变。
错在哪里?什么不见了?对于这样的 Hive 表,如何准确删除符合特定条件的特定行?
【问题讨论】:
-
为什么分区规格不同:PARTITION (date,source_key) 和 PARTITION (source_key,date)?您不需要临时表。表分区可以直接从自身中选择覆盖。
-
根据stackoverflow.com/questions/33230686/… 无法选择并插入到同一个表中。不过我还没试过。
-
这不是它在 Hive 中的工作方式。首先,执行select,结果存储在temp目录中,如果没有异常,则将结果移动到目标表目录(select和write不是并发的)。 (当然该表不在 ACID 模式下)。在 ACID 模式下,无法进行 OVERWRITE。按照我的描述,在非 ACID 表中的 INSERT OVERWRITE 可以正常工作。这个问题是关于不同的会话。只需尝试一下,您就会看到它是如何工作的。
标签: hive hdfs delete-row hadoop-partitioning table-partitioning