2014-06-12 1 views
1

Hadoop에서 Hive 쿼리를 위해 Python으로 UDF를 작성하고 있습니다. 내 테이블에는 여러 개의 bigint 필드와 여러 개의 string 필드가 있습니다.Hadoop UDF 출력 (스트리밍)에서 열 데이터 형식 유지

내 UDF는 bigint 필드를 수정하고 수정 된 버전을 새 열 (숫자 여야 함)로 빼고 string 필드를있는 그대로 둡니다.

쿼리에서 UDF를 실행하면 결과는 모두 string 개입니다.

어떻게 보존 또는 내 UDF의 출력 유형을 지정할 수 있습니다?


자세한 내용 :

내 파이썬 UDF : 나는 myudf.py으로이 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! 

.

내 하이브 쿼리 :

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

스트리밍 표준 출력을 통해 모든 것을 보냅니다. 두건 아래에있는 하 웁 스트리밍의 꼭대기에있는 래퍼입니다. 모든 유형은 문자열로 변환되어 파이썬 udf에서 적절하게 처리하고 문자열로 하이브로 돌아옵니다. 하이브의 비단뱀 변환은 문자열이 아닌 아무 것도 반환하지 않습니다. 당신은이 하위 쿼리에서 변환을 수행하려고 한 다음 유형으로 결과를 캐스팅 수 :

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가 나쁘지는 않으며 반환 유형을 지정할 수 있습니다. (아스 커에서)

업데이트 : 위의 대답은 정말 잘 작동

. 나는 몇 주 후 "프로그래밍 하이브"오라일리 책을 읽고 발견 더 우아한 해결책은 이것이다 :

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(...) 라인 유형을 지정할 수 있습니다.

관련 문제