【hive】transform脚本

文档地址:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Transform

一、介绍

和udf差不多的作用,支持用python实现。通过标准输入流从hive读取数据,内部处理完再通过标准输出流将处理结果返回给hive。实现流程上比udf要更简单灵活一些,只需要上传脚本=>add file加载到分布式缓存=>使用。

二、实现

先定义一个名为transform.py的脚本,将传入的两个字段值都+1。

py 复制代码
#!/usr/bin/env python
import sys

for line in sys.stdin:
    try:
        x, y = map(float, line.strip().split('\t'))
        x += 1
        y += 1
        print('\t'.join(map(str, [x, y])))
    except ValueError as e:
        print('\t'.join([r'\N'] * 2))

上面对输入流按照\t分隔是因为hive中的数据在传递到py脚本时,多个字段间默认会用\t分隔拼接为字符串,并且空值null会被转为字符串\N。同样将处理结果返回给hive时,如果多个字段,为了hive能够正确解析,也需要用\t拼接输出,单独的\N在hive中也会被重新解释为null。

除了单独的\N会被重新解释为null外,还有一种情况也会被hive解释为null,就是脚本里返回的字段个数小于hive中接收的字段个数时,hive中多余的字段会被赋值为null。

1.脚本上传到本地

这里的本地指的是hive主服务hive server2所在的节点,也就是我们客户端连接的那个机器。

先上传到主服务机器下的某个路径:

sh 复制代码
# 文件上传路径
[root@node1 HiveLib]# readlink -e transform.py
/root/HiveLib/transform.py

上传后通过add file命令将脚本添加到分布式缓存,之后就可以直接使用了。

sql 复制代码
-- 添加到分布式缓存
add file /root/HiveLib/transform.py;

-- 创建一个临时表测试执行
with `table` as (
    select '1' as id, '1.6789' as col1, '7.13' as col2
    union all
    select '2' as id, '11.568' as col1, null as col2
    union all
    select '3' as id, '26.09761' as col1, '71.89002' as col2
)
-- as后面接收脚本返回值的字段也可以指定字段类型, eg:(col1 double, col2 double), 省略时默认都是字符串string类型
select transform (col1, col2) using 'transform.py' as (col1, col2) from `table`;

2.脚本上传到hdfs

这种方式和本地实现基本一致,只不过需要将脚本上传到hdfs中,add file时后面跟的是hdfs路径。

sh 复制代码
[root@node1 HiveLib]# hadoop fs -put ./transform.py /user/hive/lib
[root@node1 HiveLib]# hadoop fs -ls /user/hive/lib
Found 2 items
-rw-r--r--   3 root supergroup       4164 2022-12-18 00:48 /user/hive/lib/hive_udf-1.0-SNAPSHOT.jar
-rw-r--r--   3 root supergroup        257 2024-05-05 19:13 /user/hive/lib/transform.py

sql客户端中执行:

sql 复制代码
-- 脚本路径换为hdfs路径
add file hdfs://node1:8020/user/hive/lib/transform.py;

with `table` as (
    select '1' as id, '1.6789' as col1, '7.13' as col2
    union all
    select '2' as id, '11.568' as col1, null as col2
    union all
    select '3' as id, '26.09761' as col1, '71.89002' as col2
)
select transform (col1, col2) using 'transform.py' as (col1, col2) from `table`;

三、几个需要注意的点

1.脚本名不要写全路径

using语句后面指定脚本只写脚本名即可,不要写全路径。全路径的话会报错[08S01][20000] Error while processing statement: FAILED: Execution Error, return code 20000 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. Unable to initialize custom script.,参考
https://stackoverflow.com/questions/15106127/i-met-an-error-when-i-using-hive-transform-features,我也不太理解为什么有这要求,先照做就行。

2.using后面语句中,带不带"python"的问题

这里说的是sql语句中,是using 'transform.py'还是using 'python transform.py'的问题。可以不带python这个关键字,但是前提脚本中必须指定了Shebang,类似于#!/usr/bin/env python这样,指定脚本的解释器。如果指定Shebang,using后面带不带python都可以,如果脚本中没指定,using后面必须带python这个关键字,否则报错。

看到有人说需要给py脚本chmod +x transform.py赋予可执行权限,实际操作中经过验证本地和hdfs都不需要。

3.py脚本Shebang:#!/usr/bin/env python

Shebang(也称为Hashbang)是一个源于Unix系统中的概念,特别是在类Unix操作系统中广泛使用。它是指脚本文件第一行以#!开头的特殊注释行,用于指定该脚本应该由哪个解释器程序来执行。这个名称来源于这两个起始字符---井号(#)和叹号(!)。

主要解释下#!/usr/bin/env python#!/usr/bin/python的区别。两者都是用来指定该脚本的解释器,但是前者比后者有更好的兼容性,可以理解为:后者是指定了一个固定的解释器路径,虽然多数情况下遵循规范解释器路径会在该目录下,但是并不能保证一定存在。而前者逻辑上等价于env | grep python,它是从当前所有的环境变量中按照一定的优先级顺序去找python解释器,最先找到哪个就用哪个执行,所以可以有效避免路径指定错误的问题,推荐前面这种写法。

sh 复制代码
[root@node1 HiveLib]# which python
/root/anaconda3/bin/python
[root@node1 HiveLib]# which env
/usr/bin/env
[root@node1 HiveLib]# env | grep python
CONDA_PYTHON_EXE=/root/anaconda3/bin/python
相关推荐
yumgpkpm9 小时前
Iceberg在Cloudera CDP集群详细操作步骤
大数据·人工智能·hive·zookeeper·spark·开源·cloudera
yumgpkpm11 小时前
Iceberg在Hadoop集群使用步骤(适配AI大模型)
大数据·hadoop·分布式·华为·zookeeper·开源·cloudera
清平乐的技术专栏16 小时前
Hive SQL中COALESCE 函数和NVL()函数、IFNULL函数区别
hive·hadoop·sql
爱吃大芒果16 小时前
Flutter 列表优化:ListView 性能调优与复杂列表实现
开发语言·hive·hadoop·flutter·华为
Yore Yuen16 小时前
Hive内表修改字段类型及注意事项
数据仓库·hive·hadoop
梦里不知身是客1116 小时前
yarn向hive提交队列的方式
数据仓库·hive·hadoop
Direction_Wind18 小时前
Iceberg 与 Hive 用法区别
数据仓库·hive·hadoop
本旺18 小时前
【Starrocks + Hive 】BitMap + 物化视图 实战记录
大数据·数据仓库·hive
fvafuc18 小时前
常用odps(hive)语法
数据仓库·hive·hadoop
爱吃大芒果2 天前
Flutter 本地存储方案:SharedPreferences、SQFlite 与 Hive
开发语言·javascript·hive·hadoop·flutter·华为·harmonyos