在hadoop udf输出中保留python列数据类型(流)

hmae6n7t  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(318)

我正在用python为hadoop上的配置单元查询编写一个udf。我的table有好几张 bigint 字段和几个 string 领域。
我的自定义项修改 bigint 字段,将修改后的版本减去到新列中(也应为数字),并保留 string 字段原样。
在查询中运行自定义项时,结果都是 string 柱。
如何在自定义项输出中保留或指定类型?
更多详细信息:
我的python自定义项:

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!

我把这个自定义项保存为 myudf.py 把它加到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;
lf3rwulv

lf3rwulv1#

流媒体通过标准输出发送所有内容。它实际上只是hadoop流的 Package 器。所有类型都转换为字符串,您在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 ;

hive可能会让您侥幸逃脱,如果它没有,您将需要将结果保存到一个表中,然后您可以在另一个查询中转换(强制转换)为不同的类型。
最后一个选项是只使用javaudf。只Map的udf还不错,它们允许您指定返回类型。
更新(来自asker):
上面的答案非常有效。几周后,我在阅读o'reilly的《编程Hive》一书时发现了一个更优雅的解决方案:

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(...) 线路。

相关问题