【问题标题】:set partition location in 'Insert Overwrite' dynamic partition query in hive在配置单元中的“插入覆盖”动态分区查询中设置分区位置
【发布时间】:2020-01-09 22:48:54
【问题描述】:

我创建了一个 hive 表,其基本位置指向 AWS S3 位置。 但是,我想使用“插入覆盖”查询在 HDFS 集群上创建一个分区。

以下步骤:

-- Create intermediate table
create table test_int_ash
( loc string)
partitioned by (name string, age int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
stored as textfile
location '/user/ash/test_int';

-- Insert into intermedate table with two names 'rash' and 'nash'
INSERT INTO test_int_ash partition (name="rash",age=20) values ('brisbane');
INSERT INTO test_int_ash partition (name="rash",age=30) values ('Sydney');
INSERT INTO test_int_ash partition (name="rash",age=40) values ('Melbourne');
INSERT INTO test_int_ash partition (name="rash",age=50) values ('Perth');

INSERT INTO test_int_ash partition (name="nash",age=50) values ('Auckland');
INSERT INTO test_int_ash partition (name="nash",age=40) values ('Wellington');


-- create curated table
create external table test_curated_ash
( loc string)
partitioned by (name string, age int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
stored as textfile
location 's3a://mybucket/tmp/test_curated/'; 

-- load curated table from intermedate table, using dynamic partition method, creates partitions on aws s3.
insert overwrite table test_curated_ash partition(name='rash',age)
select loc,age from test_int_ash where name='rash' ;

-- I want to keep this partition on HDFS cluster, below query doesnt work 

insert overwrite table test_curated_ash partition(name='nash',age) location 'hdfs://mynamenode/user/ash/test_curated_new'
select loc,age from test_int_ash where name='nash';

以下查询有效,但我不想使用“静态分区”方法处理它。

alter table test_curated_ash add partition(name='nash',age=40) location 'hdfs://swmcdh1/user/contexti/ash/test_curated_new/name=nash/age=40';
alter table test_curated_ash add partition(name='nash',age=50) location 'hdfs://swmcdh1/user/contexti/ash/test_curated_new/name=nash/age=50';

insert overwrite table test_curated_ash partition(name='nash',age)
select loc,age from test_int_ash where name='nash'

能否请您帮助我了解如何在“插入覆盖”动态查询中设置分区位置?

【问题讨论】:

    标签: hadoop hive cloudera hive-partitions


    【解决方案1】:

    假设我有一个名为“user”的表,我想使用 country 列对其进行动态分区。

    查询:

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    set hive.exec.max.dynamic.partitions=1000;
    set hive.exec.max.dynamic.partitions.pernode=1000;
    
    INSERT overwrite TABLE partitioned_user
        PARTITION (country)
            SELECT  firstname ,lastname,address,city,salary ,post,phone1,phone2,email,
            web,country FROM user;
    

    将数据插入分区时,需要将分区列作为查询中的最后一列。

    设置 hive.exec.dynamic.partition.mode=nonstrict;如果严格

    在 mapreduce 严格模式 (hive.mapred.mode=strict) 下,一些有风险的查询是不允许运行的。它们包括:

    1. 笛卡尔积。
    2. 没有为查询选择分区。
    3. 比较 bigint 和字符串。
    4. 比较 bigint 和 double。
    5. 无限制下单。

    根据第 2 点和第 5 点,我们不能在没有至少一个分区键过滤器的情况下使用 SELECT 语句(如 WHERE country='US')或在分区表上没有 LIMIT 条件的 ORDER BY 子句。但默认情况下,此属性设置为非严格。

    【讨论】:

    • 感谢您的回答,但我正在寻找在使用动态分区方法进行“插入覆盖”时设置分区位置。不幸的是,我无法将分区位置指定为 HDFS 集群。如果你读过我的代码,你就会明白我在做什么。
    【解决方案2】:

    您可以使用另一个中间表在 HDFS 上创建带有分区的数据。

    然后通过执行以下操作更改 Final table 中分区的位置以指向不同的位置 -

    使用数据库名;ALTER TABLE 表名 分区(部分名称=值) SET LOCATION "位置";

    或者您可以直接更新 Hive Metastore 表 SDS 以获得适当的 SD_ID

    【讨论】:

    • 您好 Saurav,希望您正确阅读我的问题。有多个子分区是动态的,我无法对其进行硬编码(在您的示例中,partname=value)。如果它只是一个列分区,这很容易,但是由于动态的多个子分区,我无法做到。无论如何,我找到了一个替代方案,不久将为此写一个博客。 - 塔
    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 2020-09-07
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多