Hive UDF Python

簡介

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    411325199308110030pony    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    411325199308110030pony    41132519950911004x  女
jack    12312423454556561   身份信息不合法!
tony    123124234545565
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章