#hadoop #hive
#hadoop #улей
Вопрос:
HDP-2.5.0.0 с использованием Ambari 2.4.0.1
Существует несколько схем баз данных SQL Server и Oracle, которые необходимо импортировать в HDFS / Hive.
Текущий подход работает нормально :
- Импорт Sqoop из СУБД в HDFS в формате avro
- Создание внешней таблицы Hive поверх файлов avro, а именно. dataaggregate_avro_compressed
- Создайте последнюю таблицу из шага.2. АВТОМАТИЗИРУЙТЕ этот шаг
- Вставьте данные из таблицы на шаге 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 для обеспечения взаимодействия с уровнем хранилища метафор улья