简介
hive为我们提供了众多的内置函数,但是在实际的运用过程中任然不能满足我们所有的需求,hive是用Java开发的,本身提供了使用Java去开发udf的方式,而这里我们采用python的方式实现udf函数。
demo实现
数据准备
我们再hive上创建一个external表,代码如下
create external table person(
name string,
idcard string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED as TEXTFILE;
field分割符使用 \t
我们将数据放入hive的warehouse中:
hdfs dfs -put person.txt /user/hive/warehouse/test_neil.db/person
或者是:
LOAD DATA LOCAL INPATH '/home/mon/data/person.txt' OVERWRITE INTO TABLE person;
使用hive function去实现
select idcard,
case when length(idcard) = 18 then
case when substring(idcard,-2,1) % 2 = 1 then '男'
when substring(idcard,-2,1) % 2 = 0 then '女'
else 'unknown' end
when length(idcard) = 15 then
case when substring(idcard,-1,1) % 2 = 1 then '男'
when substring(idcard,-1,1) % 2 = 0 then '女'
else 'unknown' end
else '不合法' end
from person;
UDF编写
如下是我们的udf代码:
# -*- coding: utf-8 -*-
import sys
for line in sys.stdin:
detail = line.strip().split("\t")
if len(detail) != 2:
continue
else:
name = detail[0]
idcard = detail[1]
if len(idcard) == 15:
if int(idcard[-1]) % 2 == 0:
print("\t".join([name,idcard,"女"]))
else:
print("\t".join([name,idcard,"男"]))
elif len(idcard) == 18:
if int(idcard[-2]) % 2 == 0:
print("\t".join([name,idcard,"女"]))
else:
print("\t".join([name,idcard,"男"]))
else:
print("\t".join([name,idcard,"身份信息不合法!"]))
测试
我们在hive中执行查询的时候,报错的提示不是很多详细,我们可以使用cat指令去测试python脚本的执行结果
我们在终端中执行如下命令:
cat person.txt | python person.py
使用
我们在HIVE中使用python定义的udf函数要借助transform函数去执行
transform函数的语法如下:
SELECT TRANSFORM (<columns>)
USING 'python <python_script>'
AS (<columns>)
FROM <table>;
transfrom和as的columns的个数不必一致.
我们首先需要将我们的person.py加载入
我们在hive中去执行如下代码:
add file /xxx/person.py
xxx为本地文件的路径.
然后使用transform函数执行:
select transform(name,idcard) USING 'python person.py' AS (name,idcard,gender) from person;