2014-06-12 3 views
1

Я пишу UDF в Python для запроса Hive на Hadoop. В моей таблице есть несколько полей bigint и несколько полей string.Сохранение типов данных столбцов в выходном сигнале Hadoop UDF (потоковое)

My UDF изменяет поля bigint, вычитает измененные версии в новый столбец (также должен быть числовым) и оставляет поля string как есть.

Когда я запускаю свой UDF в запросе, все результаты - string.

Как сохранить или указать типы в моем выходе UDF?


Подробнее:

Моего Python UDF:

import sys 
for line in sys.stdin: 
    # pre-process row 
    line = line.strip() 
    inputs = line.split('\t') 

    # modify numeric fields, calculate new field 
    inputs[0], inputs[1], new_field = process(int(inputs[0]), int(inputs[1])) 

    # leave rest of inputs as is; they are string fields. 

    # output row 
    outputs = [new_field] 
    outputs.extend(inputs) 
    print '\t'.join([str(i) for i in outputs]) # doesn't preserve types! 

Я сохранил эту UDF, как myudf.py и добавил его в улей.

Мой Улей запрос:

CREATE TABLE calculated_tbl AS 
SELECT TRANSFORM(bigintfield1, bigintfield2, stringfield1, stringfield2) 
USING 'python myudf.py' 
AS (calculated_int, modified_bif1, modified_bif2, stringfield1, stringfield2) 
FROM original_tbl; 

ответ

1

Streaming посылает все через стандартный вывод. На самом деле это всего лишь обертка поверх потопа хаопа под капотом. Все типы преобразуются в строки, которые вы обрабатывали соответственно в python udf, и возвращаетесь в улей как строки. Преобразование python в улье никогда не вернет ничего, кроме строк. Вы могли бы попытаться сделать преобразование в подзапросе, а затем привести результаты к типу:

SELECT cast(calculated_int as bigint) 
     ,cast(modified_bif1 as bigint) 
     ,cast(modified_bif2 as bigint) 
     ,stringfield1 
     ,stringfield2 
FROM ( 
SELECT TRANSFORM(bigintfield1, bigintfield2, stringfield1, stringfield2) 
USING 'python myudf.py' 
AS (calculated_int, modified_bif1, modified_bif2, stringfield1, stringfield2) 
FROM original_tbl) A ; 

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

Окончательный вариант - просто использовать Java UDF. Карты только UDF не так уж плохи, и они позволяют указывать типы возвращаемых данных.

Update (от спрашивающего):

выше ответ работает очень хорошо. Более элегантное решение, которое я нашел чтение «Программирование Улей» O'Reilly книгу несколько недель спустя это:

CREATE TABLE calculated_tbl AS 
SELECT TRANSFORM(bigintfield1, bigintfield2, stringfield1, stringfield2) 
USING 'python myudf.py' 
AS (calculated_int BIGINT, modified_bif1 BIGINT, modified_bif2 BIGINT, stringfield1 STRING, stringfield2 STRING) 
FROM original_tbl; 

Вместо литья, вы можете указать типы прямо в AS(...) линии.

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