Hive 处理数据时遇到复杂情况,可以考虑改写 sparkSql 或者 直接调用 transform 写 python,这里整理一下用 python 写 transform 写法:
1.实现 -- 思路
transform 是 hive 自带函数,搭配 python 处理复杂业务逻辑非常实用,需要准备两个文件即可,xxxx.sh,yyyy.py。
xxxx.sh 负责从 hive 表中提取要处理的字段,yyyy.py 负责处理上一步提取的字段并重新输出自己要的内容,然后可以选择将内容
插入到另一张 hive 表,也可以输出到 hdfs 。
2.实现 -- xxxx.sh
#!/bin/bash
hive -e "
add file yyyy.py;
insert overwrite table your_table partition(dt=$day)
select transform(*)
using 'python yyyy.py'
as (feat1,feat2,...,featN)
from
(select * from feat_table) tmp;
"
-> add file:
添加所用 python 文件,如果 python 内需要读取额外的文件,需要把额外的文件也添加到脚本中,例:add file abc.txt。
-> insert:
这里的写法是插入到对应分区表,如果不需要也可以直接写入 HDFS:
insert overwrite directory '/user/xxx/xxx/xxx'
-> transform:
transform(*) 针对 tmp 表 选中的所有字段进行处理,也可以只选中 tmp 表中个别字段,对应修改为:
transform(feat1,feat2,...,featM)
-> using as:
using 选择我们要用的 python 文件,这里 as 后面的字段与 yyyy.py 输出的字段需保持一致,例如 as 后面输出三个字段a,b,c
则对应 yyyy.py 输出也应该是三个字段。
-> from:
from 后面的语句相当于数据来源,这里也可以 join 更多的表,加入更多的限制条件
3.实现 -- yyyy.py
# coding=utf-8
import sys
for line in sys.stdin:
cols = line.strip().split('\t')
name = clos[0]
age = cols[1]
gender = cols[2]
print(name + '\t' + age + '\t' + gender)
yyyy.py 主要实现自己的处理逻辑,这里只是最简单的 demo,有两个注意的点:
-> 分割符
解析 line 生成 cols 时,分隔符要与上面 xxxx.sh 的 tmp 表对应,如果是 hive 默认分隔符 ^A,则需要用 '\001' 分割,如果是建表时自定义了分割符,则需要用自定义分割符
-> 输出
这里输出的内容要和 xxxx.sh 里 as (feat1,feat2,...,featN) 对应的内容数量相匹配,分隔符要和 your_table 的分隔符保持一致。