Изменить (ПУСТУЮ) таблицу, добавить столбец раздела

#hadoop #hive

#hadoop #улей

Вопрос:

HDP-2.5.0.0 с использованием Ambari 2.4.0.1

Существует несколько схем баз данных SQL Server и Oracle, которые необходимо импортировать в HDFS / Hive.

Текущий подход работает нормально :

  1. Импорт Sqoop из СУБД в HDFS в формате avro
  2. Создание внешней таблицы Hive поверх файлов avro, а именно. dataaggregate_avro_compressed
  3. Создайте последнюю таблицу из шага.2. АВТОМАТИЗИРУЙТЕ этот шаг
  4. Вставьте данные из таблицы на шаге 2. в итоговую таблицу

Теперь Step3. table должен быть ORC СЖАТЫМ РАЗДЕЛЕННЫМ и, возможно, УПРАВЛЯЕМЫМ. Вручную можно выполнить следующее :

 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 пустая таблица

    СОЗДАЙТЕ ТАБЛИЦУ dataaggregate_orc_empty, ПОДОБНУЮ dataaggregate_avro_compressed В ФОРМАТЕ СТРОКИ 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.OrcInputFormat..OrcOutputFormat’ TBLPROPERTIES (‘orc.compress’=’ZLIB’);

Теперь эта таблица содержит столбец раздела datedimensionid, который необходимо удалить из таблицы, но «изменить столбец удаления таблицы» не поддерживается

  • CTAS с использованием спецификации столбца регулярных выражений. :

    установите hive.support.quoted.identifiers=none; СОЗДАЙТЕ ТАБЛИЦУ dataaggregate_orc_empty КАК ВЫБРАННУЮ (datedimensionid)? . ИЗ dataaggregate_avro_compressed limit 0;

Это создает таблицу без столбца раздела datedimensionid, но теперь, как изменить эту пустую таблицу, чтобы включить столбец раздела, здесь даже первый подход натыкается на стену! В документации говорится о добавлении разделов со спецификацией, но на данном этапе у меня ее нет — я просто хочу, чтобы эта таблица была похожа на таблицу, созданную вручную (показано в начале сообщения).

Как мне поступить?

Комментарии:

1. HiveMetaStoreClient может помочь вашему требованию. Я дал примерный подход, таким образом, мы модифицировали разделы. вы можете попробовать

Ответ №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;
        }
    }
}
 

Комментарии:

1. Но методы в классе, например; add_partition(раздел new_part), похоже, не решают мою проблему — добавление столбца раздела в пустую таблицу, т.е. Нет данных или значений для раздела.

2. вы пробовали это? AFAIK its также должен работать с пустой таблицей

3. этот класс HiveMetaStoreClient используется другими движками sql для обеспечения взаимодействия с уровнем хранилища метафор улья