【问题标题】:How to add one extra partition to external hive table?如何向外部配置单元表添加一个额外的分区?
【发布时间】:2021-08-12 13:35:28
【问题描述】:

我有如下的蜂巢表

create external table transaction(
    id int,
    name varchar(60))
    month string
  )
  PARTITIONED BY (
  year string, 
  transaction_type_code varchar(20)
  )
  STORED AS PARQUET 
  LOCATION 'hdfs://xyz';

我正在创建一个带有多个分区列 dt 的另外一个外部表,如下所示

create external table transaction_copy(
    id int,
    name varchar(60))
    month string
  )
  PARTITIONED BY (
  dt string,
  year string, 
  transaction_type_code varchar(20)
  )
  STORED AS PARQUET 
  LOCATION 'hdfs://xyz';

如下添加分区

alter table transaction_copy add if not exists partition (dt='20210811') LOCATION 'hdfs://xyz';

遇到异常

ERROR: Error while compiling statement: FAILED: ValidationFailureSemanticException partition spec {dt=20210810} doesn't contain all (3) partition columns

我可以通过传递所有 3 个分区来添加分区。

是否也可以只传递一个分区?

【问题讨论】:

    标签: hive hadoop2 hadoop-partitioning data-partitioning hiveddl


    【解决方案1】:

    无法添加分区并仅指定三列中的一列,因为 Hive 中的分区是分层的,而 hdfs 上的分区是分层文件夹:

    table location
    ----------------------
       |                |     ...
      dt1              dt2    ...
    ______________...  __________
      |        |        |       |
      year=1  year=2    year3  ....
       ...     |
              -------------------------
              |                     |
      transaction_type_code = 1   transaction_type_code = 2
    

    每个分区位置路径如下所示
    hdfs://blabla-my-dwh/table_name/dt=1/year=1/transaction_type_code=1

    数据文件通常位于叶路径文件夹中,但是,您可以在 hdfs 中指定一些不在此层次结构中的自定义位置,但是 patition 的元数据应该包含所有列,因为没有所有列就无法识别完全分区。

    顺便说一句,如果dt 是一个日期,而year 可以从同一个dt 派生,那么这样的分区是没有意义的,因为每个日期将只包含一年。

    此外,如果您要创建具有三个分区列的外部表,请确保您已经在分层文件夹中组织了数据,除非您要手动为每个分区指定一些自定义位置。 CREATE EXTERNAL TABLE 不会为您重新组织数据,如果每个分区都没有数据文件夹,它将无法工作。

    如果您有现有的分区表并希望使用不同的分区模式重新分区,那么您需要重新加载数据:

    1. 使用新分区创建新表
    2. 加载数据
        set hive.exec.dynamic.partition=true;
        set hive.exec.dynamic.partition.mode=nonstrict;
        
        insert overwrite table my_new_table partition (day, month, year) 
        select col1, col2 ...,
               day, month, year  --partition columns shold be the last
         from my_old_table;
    
    1. 删除旧表(如果不需要,也删除文件夹),必要时重命名新表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2013-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多