HIve: формат данных изменяется при преобразовании из ИЛИ C в ТЕКСТ - PullRequest
2 голосов
/ 15 февраля 2020

У меня есть таблица улья со следующей схемой:

CREATE EXTERNAL TABLE db_test.user_arry(
  cstid string, 
  prdctsslctd array<string>, 
  indvprc array<bigint>, 
  dscntamt array<bigint>, 
  prdctsrjctd array<string>)
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY ',' 
  LINES TERMINATED BY '\n'
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
   '/location/on/a/hadoop/'

Данные, представленные в ней, представлены в следующем формате:

--------------------------------------------------------  
 name | prdctsslctd | indvprc | dscntamt | prdctsrjctd 
--------------------------------------------------------   
 cctg65  ["m_jns","cbyht"]        ["23","6"]       ["1","1"] ["shs","jkt"]
 jju89o0 ["top","jeans_wmn"]      ["55","45"]      [NULL]         [NULL]
 ju34hd  ["laychps","candy","toy"]["3","5","67"]["12","8"]["candy"]

Попытка вытащить эти данные в таблицу, имеющую тип данных как string для всех столбцов

CREATE EXTERNAL TABLE db_test.user_strng(
  cstid string, 
  prdctsslctd string, 
  indvprc string, 
  dscntamt string, 
  prdctsrjctd string)
ROW FORMAT DELIMITED 
 FIELDS TERMINATED BY ',' 
 LINES TERMINATED BY '\n'
STORED AS textfile
LOCATION
 '/location/on/a/hadoop/';

Использование:

insert into db_test.user_strng select * from db_test.user_arry;

Фактический O / P:

--------------------------------------------------------  
 name | prdctsslctd | indvprc | dscntamt | prdctsrjctd 
--------------------------------------------------------   
 cctg65  m_jnscbyht        236       11     shsjkt
 jju89o0 topjeans_wmn      5545      NULL   NULL
 ju34hd  laychpscandytoy   3567      128    candy

Ожидаемый O / P:

--------------------------------------------------------  
 name | prdctsslctd | indvprc | dscntamt | prdctsrjctd 
--------------------------------------------------------   
 cctg65  "m_jns","cbyht"          "23","6"         "1","1"   "shs","jkt"
 jju89o0 "top","jeans_wmn"        "55","45"         NULL           NULL
 ju34hd  "laychps","candy","toy"  "3","5","67"     "12","8"  "candy"

Не понять, что происходит, или что-то упустить?

Update_1

O / P из таблицы после выполнения преобразования массива в массив:

ALTER TABLE user_arry CHANGE indvprc indvprc array<string>;
ALTER TABLE user_arry CHANGE dscntamt dscntamt array<string>;


--------------------------------------------------------  
 name | prdctsslctd | indvprc | dscntamt | prdctsrjctd 
--------------------------------------------------------   
 cctg65  ["m_jns","cbyht"]        ["23","6"]       ["1","1"] ["shs","jkt"]
 jju89o0 ["top","jeans_wmn"]      ["55","45"]      []         []
 ju34hd  ["laychps","candy","toy"]["3","5","67"]["12","8"]["candy"]

Окончательный O / P из таблицы, где все типы данных являются строками:

--------------------------------------------------------  
 name | prdctsslctd | indvprc | dscntamt | prdctsrjctd 
--------------------------------------------------------   
 cctg65  m_jns    cbyht      23   6    1      1      shs  jkt
 jju89o0 top      jeans_wmn  55   45       
 ju34hd  laychps  candy      toy  3    5      67     12    8    candy

По-прежнему не получается нужное значение o / p.

Update_2

Как и предполагалось, изменилось ли значение с FIELDS TERMINATED BY ',' на FIELDS TERMINATED BY '\t'. Получение данных в нужном формате.

1 Ответ

1 голос
/ 15 февраля 2020

Измените тип всех массивов на array <string>:

alter table ALTER TABLE user_arry CHANGE indvprc indvprc array<string>;
alter table ALTER TABLE user_arry CHANGE dscntamt dscntamt array<string>;

И, согласно вашему примеру с данными, array<bigint> не подходит для таких значений, как "23.45". array<string> должно нормально работать с вашим файлом данных.

Используйте concat_ws для преобразования массивов в строки, разделенные запятыми:

insert into db_test.user_strng 
select  name, 
        concat_ws(',',prdctsslctd)  as prdctsslctd,
        concat_ws(',',indvprc)      as indvprc,
        concat_ws(',',dscntamt)     as dscntamt,
        concat_ws(',',prdctsrjctd) as prdctsrjctd 
  from db_test.user_arry;
...