簡介
Hive爲我們提供了衆多的內置函數,但是在實際的運用過程中仍然不能滿足我們所有的需求.hive是用java開發的,本身提供了使用java去開發UDF的方式.而這裏我們採用python的方式去實現UDF函數.
DEMO實現
我們這裏用python自定義函數,去實現一個方法,利用身份證號去判斷性別(18位身份證的倒數第二位偶數爲女,奇數爲男.15位身份證的倒數第一位偶數爲女,奇數爲男.).其實這個需求可以使用hive自帶的function去進行解決.我們接下來使用2種方式去實現這個需求.
數據準備
我們在hive上創建一個external表(名字person表),執行如下代碼:
create external table person(
name string,
idcard string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED as TEXTFILE;
該表兩個字段,一個爲name,另一個爲idcard
數據格式如下:
neil 411326199402110030
pony 41132519950911004x
jcak 12312423454556561
tony 412345671234908
field分隔符使用\t
我們將數據放入hive的warehouse中:
hdfs dfs -put person.txt /user/hive/warehouse/test_neil.db/person
執行select,我們發現數據已經進入到hive了.
使用Hive Function去實現
我們可以執行一下的hql去實現
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;
得到的結果如下(beeline下):
+---------------------+------+--+
| idcard | _c1 |
+---------------------+------+--+
| 12312423454556561 | 不合法 |
| 123124234545565 | 男 |
| 411325199308110030 | 男 |
| 41132519950911004x | 女 |
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,"身份信息不合法!"]))
這裏我們使用python的重定向,將hive控制檯的輸出進行split,split默認使用的爲\t.然後根據split後的idcard的倒數第二位進行判斷這個人的性別.
測試
我們在hive中去執行查詢時,報錯的提示不是很詳細.我們可以使用cat指令去測試python腳本的執行效果.
我們在終端中執行如下指令:
cat person.txt|python person.py
輸入結果如下:
neil 411325199308110030 男
pony 41132519950911004x 女
jack 12312423454556561 身份信息不合法!
tony 123124234545565 男
說明我們的解析是成功的.
使用
我們在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;
我們同樣可以得到如下的結果:
neil 411325199308110030 男
pony 41132519950911004x 女
jack 12312423454556561 身份信息不合法!
tony 123124234545565 男