我正在用Python编写一个UDF,用于Hadoop上的Hive查询。我的表格包含多个bigint
字段和多个string
字段。
我的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
并将其添加到Hive。
我的Hive查询:
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;
答案 0 :(得分:1)
Streaming通过stdout发送所有内容。它实际上只是在引擎盖下的hadoop流媒体上的一个包装器。所有类型都转换为字符串,您在python udf中相应地处理它们,并作为字符串返回到hive。配置单元中的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 ;
Hive可能会让你逃避这个,如果没有,你需要将结果保存到表中,然后你可以在另一个查询中转换(强制转换)为另一种类型。
它只是使用Java UDF的最终选项。仅映射UDF也不错,它们允许您指定返回类型。
更新(来自提问者):
上述答案非常有效。一个更优雅的解决方案,我发现阅读"编程蜂巢"几周后,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(...)
行中指定类型,而不是强制转换。