Hive - 在 Python UDF 中处理 NULL 输入值

Posted

技术标签:

【中文标题】Hive - 在 Python UDF 中处理 NULL 输入值【英文标题】:Hive - handling NULL input values in Python UDF 【发布时间】:2019-06-19 03:17:29 【问题描述】:

在python中写hiveUDFs时,如何处理NULL输入值?。

重现错误的示例设置:

蜂巢表:

CREATE external table udfTest(
fname STRING,
age INT
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '<location>';

输入.txt:

abc    1
efg    2
       3 //missing fname
hij      //missing age

加载数据:

LOAD DATA INPATH '/tmp/input.txt' INTO TABLE udfTest;

Python UDF 将年龄增加 1:

import sys
import datetime
for line in sys.stdin:
        fname, age = line.strip('\n').split('\t')
        fname = fname.upper() if (fname is not None and fname != '') else 'dummy'
        age = int(age) if (age is not None and age.strip() != 'NULL') else -1
        print '\t'.join(map(str, [fname, age]))

加载 UDF 并在 hive 中调用它:

add FILE /tmp/example.py
SELECT TRANSFORM(fname, age) USING 'python /tmp/example.py' AS (fname, age) FROM udfTest;

错误,我得到了:

已结束作业 = job_1560326504017_73073 错误作业期间出错, 获取调试信息... 检查任务 ID: task_1560326504017_73073_m_000000(和更多)来自工作 job_1560326504017_73073

失败次数最多的任务(4): -----任务ID:task_1560326504017_73073_m_000000

网址:

----- 此任务的诊断消息:错误:java.lang.RuntimeException:Hive 运行时错误,同时关闭运算符 在 org.apache.hadoop.hive.ql.exec.mr.ExecMapper.close(ExecMapper.java:217) 在 org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:61) 在 org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:459) 在 org.apache.hadoop.mapred.MapTask.run(MapTask.java:343) 在 org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164) 在 java.security.AccessController.doPrivileged(Native Method) 在 javax.security.auth.Subject.doAs(Subject.java:422) 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1924) 在 org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158) 引起 作者:org.apache.hadoop.hive.ql.metadata.HiveException:[错误 20003]: 尝试关闭运行您的操作员时发生错误 自定义脚本。在 org.apache.hadoop.hive.ql.exec.ScriptOperator.close(ScriptOperator.java:572) 在 org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610) 在 org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610) 在 org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610) 在 org.apache.hadoop.hive.ql.exec.mr.ExecMapper.close(ExecMapper.java:199) ... 8 更多

FAILED:执行错误,返回代码 20003 来自 org.apache.hadoop.hive.ql.exec.mr.MapRedTask。发生错误时 试图关闭运行自定义脚本的 Operator。

已编辑:

select * from udfTest;
abc    1
efg    2
       3
hij    NULL

【问题讨论】:

您能否发布select * from udfTest 的结果,以确保您的文件被正确解析?然后我建议你在 bash cat input.txt | python udf.py 中本地测试你的 UDF @serge_k,已添加 能否也检查一下字符串列select length(fname) from udfTest的长度? @serge_k,我已经在本地调试了 UDF,我只需要知道如何在 python UDF 中从 Hive 检查 NULL 值,以便我可以插入默认值来代替 NULL。跨度> 尝试直接在 Hive 中进行,例如,SELECT TRANSFORM(fname, coalesce(age, -1)) 【参考方案1】:

“默认情况下,列将转换为 STRING 并由 TAB 分隔,然后再提供给用户脚本;类似地,所有 NULL 值都将转换为文字字符串 \N 以区分 NULL 值和空字符串。”更多详情here。因此,您需要检查您的列是否为'\N'

【讨论】:

这似乎不起作用,我使用的 if 条件是:if(fname is not None and fname != '' and fname != '\N') 抱歉,调用脚本时犯了一个愚蠢的错误。现在解决了。你是对的

以上是关于Hive - 在 Python UDF 中处理 NULL 输入值的主要内容,如果未能解决你的问题,请参考以下文章

Spark(Hive) SQL中UDF的使用(Python)

Hive自定义UDF函数

在 hive 中注册 python 自定义 UDF

处理 hive udf 中的多行

Hive UDF 在 Scala 中处理整数数组

在Hive中通过Java和Python实现UDF进行对比