如何从分区配置单元表中删除行



我需要从分区的Hive表中删除特定的行。这些要删除的行符合某些条件,因此不能删除整个分区。假设表Table有三列:partnerdatesource_key,它由datesource_key分区。

众所周知,配置单元中不支持删除或更新特定记录集的操作(请参阅如何删除和更新配置单元中的记录(。

根据这个解决方案,我成功地执行了以下查询,以便只保留符合某些给定条件的记录,例如:属于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'的记录都保持在给定的日期范围内,并且基本上保持不变。

故障在哪里?缺少什么?如何准确地删除与此类配置单元表的某些条件相匹配的特定行?

表分区可以通过select from本身+WHERE过滤器直接覆盖。场景非常简单,您不需要任何临时表。如果您不确定会发生什么,请制作备份表。

  1. 如果您想删除整个分区(而不是覆盖(,请执行

    ALTER TABLE TableName DROP IF EXISTS
    PARTITION (<partition spec to be dropped>); --check partition spec to be dropped carefully
    

如果没有要删除的分区,请跳过此操作。

  1. 用筛选的行覆盖其他分区:

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    set hive.allow.move.on.s3=true; --If you are on Qubole/S3
    insert overwrite table TableName partition (date, source_key ) --partition spec should match table DDL
    select * from TableName 
    where <condition> --condition should be True for rows which NOT be deleted
    

您的代码相当混乱,因为您使用LIKE创建了临时表,但使用了不同的分区规范并选择了*(与原始表中的列顺序相同(。列的顺序必须完全匹配,分区列是最后一列,顺序也相同。

相关内容

  • 没有找到相关文章

最新更新