2015-02-19 5 views
2

Я создал таблицу, используя следующую команду -Hive создание таблицы с помощью OpenCsv SerDe

create table cust(event int, pid int, REQ_FROM_IP int, REQ_CITY_ID int, REQ_STATE_ID int, REQ_COUNTRY_ID int, key String) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'                     
WITH SERDEPROPERTIES (                              
    "separatorChar" = "|",                              
    "quoteChar"  = "'",                              
    "escapeChar" = "\\"                              
)STORED AS TEXTFILE; 

Однако созданная таблица имеет все coloumns как строка!

desc cust; 
    OK 
event     string     from deserializer 
pid      string     from deserializer 
req_from_ip    string     from deserializer 
req_city_id    string     from deserializer 
req_state_id   string     from deserializer 
req_country_id   string     from deserializer 
key      string     from deserializer 

Действительно ли это SerDe возится с структурой данных?

ответ

2

Из-за просмотра исходного кода, похоже, что OpenCSVSerde всегда выводит столбцы строки без учета того, какие типы были фактически указаны в запросе HiveQL.

Потенциальные (не очень красиво) Обойти это могло бы использовать OpenCSVSerde для форматирования промежуточной таблицы (определение может быть идентично тому, что в настоящее время для cust, может назвать это cust_staging. Если ваш случай использования является то, что вы пытаетесь загрузить данные в этом формате и пытаясь работать с ним в Hive с «правильными» типами данных, вы можете заполнить cust_staging, как обычно бы загрузили таблицу, а затем заполнили свою целевую таблицу cust оператором CTAS, например :

CREATE TABLE cust AS SELECT 
    CAST(event AS INT) AS event, 
    CAST(pid AS INT) AS pid, 
    CAST(REQ_FROM_IP AS INT) AS REQ_FROM_IP, 
    CAST(REQ_CITY_ID AS INT) AS REQ_CITY_ID, 
    CAST(REQ_STATE_ID AS INT) AS REQ_STATE_ID, 
    CAST(REQ_COUNTRY_ID AS INT) AS REQ_COUNTRY_ID, 
    key 
FROM cust_staging; 

cust И теперь будут иметь типы столбцов, вы ожидали:

hive> DESCRIBE cust; 
OK 
event      int         
pid       int         
req_from_ip     int         
req_city_id     int         
req_state_id    int         
req_country_id    int         
key       string        
Time taken: 0.546 seconds, Fetched: 7 row(s) 

За отличный вход с @JeremyBeard, если все в порядке с никогда не материализуется данные с его «правильным» типов, cust может быть на самом деле вид:

CREATE VIEW `cust` -- All the other stuff is the same 

Для дальнейшего бурения Открыть если ваш прецедент полностью доступен только для чтения (вам никогда не нужно действительно изменять эти данные), вы можете определить cust_staging как внешнюю таблицу (которая по-прежнему использует OpenCSVSerde), которая указывает на файлы данных, разделенные каналом, а затем определите cust в виде внешней таблицы.

Однако, если ваш случай использования состоит в том, что вам нужно хранить таблицу с нестроковыми столбцами в формате OpenCSVSerde, то вы все равно можете создать таблицу cust_staging (опять же, с тем же определением, что и было изначально), и заполнить данные в обратное направление:

INSERT INTO TABLE cust_staging SELECT * FROM cust; 

И если все, что до сих пор чувствует себя не вполне достаточно элегантно (понятно) - решение может быть продлить OpenCSVSerde в пользовательский SerDe, который будет делать то, что вы хотите, чтобы это сделать, без необходимости для промежуточных промежуточных таблиц.

+2

Вариант этого преобразования состоит в том, чтобы преобразовать этот CTAS в представление, чтобы данные могли считываться из исходных файлов без этапа предварительного преобразования. –

+0

@JeremyBeard +1 Спасибо и хорошо заметили - я добавил обсуждение этого вопроса в ответ, а также еще один вариант, реализующий представление во внешней таблице, в случае, если прецедент используется только для чтения. – rchang

+0

@rchang, JeremyBeard Спасибо за помощь. Однако я просто сделал числовые операции над числами, представленными как строки. (Была ли сумма req_state_id, хотя и не логичная, а только для тестирования). Я обнаружил, что он работает отлично, что устанавливает, что бегун запросов в Hive слабо типизирован. Итак, есть ли необходимость в использовании реальных типов, когда я могу выполнять те же операции над числовыми строками? –

Смежные вопросы