【问题标题】:Alter (EMPTY) table add partition COLUMNAlter (EMPTY) 表添加分区 COLUMN
【发布时间】:2017-02-26 08:49:44
【问题描述】:

HDP-2.5.0.0 使用 Ambari 2.4.0.1

有几个 SQL Server 和 Oracle 数据库架构需要导入到 HDFS/Hive。

目前的方法运行良好:

  1. Sqoop 以 avro 格式从 RDBMS 导入 HDFS
  2. 在 avro 文件上创建 Hive 外部表,即。 dataaggregate_avro_compressed
  3. 从 step.2 创建最终表。 自动执行此步骤
  4. 将第 2 步中的表格中的数据插入到最终表格中

现在,第 3 步。表必须是 ORC + COMPRESSED + PARTITIONED 并且可能是 MANAGED。手动,可以完成以下操作:

CREATE TABLE `dataaggregate_orc_empty`( ......)PARTITIONED BY (`datedimensionid` bigint)  ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' TBLPROPERTIES ('orc.compress'='ZLIB');

但它是自动创建是一个挑战,我正在努力使用以下方法:

  • CTAS 空表

    CREATE TABLE dataaggregate_orc_empty LIKE dataaggregate_avro_compressed ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' 存储为 INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' OUTPUTFORMAT ' org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' TBLPROPERTIES ('orc.compress'='ZLIB');

现在,此表包含需要从表中删除的分区列 datedimensionid,但不支持“更改表删除列”

  • CTAS 使用REGEX column spec。 :

    设置 hive.support.quoted.identifiers=none; CREATE TABLE dataaggregate_orc_empty AS SELECT (datedimensionid)?+.+ FROM dataaggregate_avro_compressed limit 0;

这将创建没有分区列 datedimensionid 的表,但是现在如何更改这个空表以包含分区列,这就是第一种方法遇到的问题! documentation talks about adding partitions 有一个规范,但我在这个阶段没有一个 - 我只是希望这个表和手动创建的一样(显示在帖子的开头)。

我该怎么做?

【问题讨论】:

  • HiveMetaStoreClient 可能对您的要求有所帮助。我以这种方式给出了示例方法,我们修改了分区。你可以试试

标签: hadoop hive


【解决方案1】:

这是连接HiveMetaStoreClient的一种方法,您可以使用方法alter partition。

在这个类和列中,可以提取所有其他信息,如分区。请。请参阅示例客户端和方法。

import org.apache.hadoop.hive.conf.HiveConf;

// test program
public class Test {
    public static void main(String[] args){

        HiveConf hiveConf = new HiveConf();
        hiveConf.setIntVar(HiveConf.ConfVars.METASTORETHRIFTCONNECTIONRETRIES, 3);
        hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, "thrift://host:port");

        HiveMetaStoreConnector hiveMetaStoreConnector = new HiveMetaStoreConnector(hiveConf);
        if(hiveMetaStoreConnector != null){
            System.out.print(hiveMetaStoreConnector.getAllPartitionInfo("tablename"));
        }
    }
}


// define a class like this

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
import org.apache.hadoop.hive.ql.metadata.Hive;
import org.apache.thrift.TException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class HiveMetaStoreConnector {
    private HiveConf hiveConf;
    HiveMetaStoreClient hiveMetaStoreClient;

    public HiveMetaStoreConnector(String msAddr, String msPort){
        try {
            hiveConf = new HiveConf();
            hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, msAddr+":"+ msPort);
            hiveMetaStoreClient = new HiveMetaStoreClient(hiveConf);
        } catch (MetaException e) {
            e.printStackTrace();
            System.err.println("Constructor error");
            System.err.println(e.toString());
            System.exit(-100);
        }
    }

    public HiveMetaStoreConnector(HiveConf hiveConf){
        try {
            this.hiveConf = hiveConf;
            hiveMetaStoreClient = new HiveMetaStoreClient(hiveConf);
        } catch (MetaException e) {
            e.printStackTrace();
            System.err.println("Constructor error");
            System.err.println(e.toString());
            System.exit(-100);
        }
    }

    public String getAllPartitionInfo(String dbName){
        List<String> res = Lists.newArrayList();
        try {
            List<String> tableList = hiveMetaStoreClient.getAllTables(dbName);
            for(String tableName:tableList){
                res.addAll(getTablePartitionInformation(dbName,tableName));
            }
        } catch (MetaException e) {
            e.printStackTrace();
            System.out.println("getAllTableStatistic error");
            System.out.println(e.toString());
            System.exit(-100);
        }

        return Joiner.on("\n").join(res);
    }

    public List<String> getTablePartitionInformation(String dbName, String tableName){
        List<String> partitionsInfo = Lists.newArrayList();
        try {
            List<String> partitionNames = hiveMetaStoreClient.listPartitionNames(dbName,tableName, (short) 10000);
            List<Partition> partitions = hiveMetaStoreClient.listPartitions(dbName,tableName, (short) 10000);
            for(Partition partition:partitions){
                StringBuffer sb = new StringBuffer();
                sb.append(tableName);
                sb.append("\t");
                List<String> partitionValues = partition.getValues();
                if(partitionValues.size()<4){
                    int size = partitionValues.size();
                    for(int j=0; j<4-size;j++){
                        partitionValues.add("null");
                    }
                }
                sb.append(Joiner.on("\t").join(partitionValues));
                sb.append("\t");
                DateTime createDate = new DateTime((long)partition.getCreateTime()*1000);
                sb.append(createDate.toString("yyyy-MM-dd HH:mm:ss"));
                partitionsInfo.add(sb.toString());
            }

        } catch (TException e) {
            e.printStackTrace();
            return Arrays.asList(new String[]{"error for request on" + tableName});
        }

        return partitionsInfo;
    }

    public String getAllTableStatistic(String dbName){
        List<String> res = Lists.newArrayList();
        try {
            List<String> tableList = hiveMetaStoreClient.getAllTables(dbName);
            for(String tableName:tableList){
                res.addAll(getTableColumnsInformation(dbName,tableName));
            }
        } catch (MetaException e) {
            e.printStackTrace();
            System.out.println("getAllTableStatistic error");
            System.out.println(e.toString());
            System.exit(-100);
        }

        return Joiner.on("\n").join(res);
    }

    public List<String> getTableColumnsInformation(String dbName, String tableName){
        try {
            List<FieldSchema> fields = hiveMetaStoreClient.getFields(dbName, tableName);
            List<String> infs = Lists.newArrayList();
            int cnt = 0;
            for(FieldSchema fs : fields){
                StringBuffer sb = new StringBuffer();
                sb.append(tableName);
                sb.append("\t");
                sb.append(cnt);
                sb.append("\t");
                cnt++;
                sb.append(fs.getName());
                sb.append("\t");
                sb.append(fs.getType());
                sb.append("\t");
                sb.append(fs.getComment());
                infs.add(sb.toString());
            }

            return infs;

        } catch (TException e) {
            e.printStackTrace();
            System.out.println("getTableColumnsInformation error");
            System.out.println(e.toString());
            System.exit(-100);
            return null;
        }
    }
}

【讨论】:

  • 但是类中的方法,例如; add_partition(Partition new_part) 似乎没有解决我的问题 - 将分区列添加到空表,即分区没有数据或值。
  • 你试过了吗? AFAIK 它也应该适用于空表
  • 此类 HiveMetaStoreClient 被其他 sql 引擎用于与 hive 元存储级别具有互操作性
猜你喜欢
  • 2013-03-19
  • 1970-01-01
  • 2021-04-01
  • 2020-07-01
  • 2017-05-08
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 2017-08-05
相关资源
最近更新 更多