Hive是一个数据仓库,用于查询和聚合驻留在HDFS上的大型数据集。
标准INSERT INTO
语法表现不佳,因为:
话虽如此,现在有一个Hive / HCatalog的Streaming API,详见here。
我面临着使用Python将数据以速度方式插入Hive的需求。我知道pyhive
和pyhs2
库,但它们似乎都没有使用Streaming API。
有没有人成功设法让Python使用Streaming API向Hive插入许多行,这是怎么做到的?
我期待您的见解!
答案 0 :(得分:1)
Hive用户可以通过脚本流表来转换该数据: ADD FILE replace-nan-with-zeros.py;
SELECT
TRANSFORM (...)
USING 'python replace-nan-with-zeros.py'
AS (...)
FROM some_table;
这是一个简单的Python脚本:
#!/usr/bin/env python
import sys
kFirstColumns= 7
def main(argv):
for line in sys.stdin:
line = line.strip();
inputs = line.split('\t')
# replace NaNs with zeros
outputs = [ ]
columnIndex = 1;
for value in inputs:
newValue = value
if columnIndex > kFirstColumns:
newValue = value.replace('NaN','0.0')
outputs.append(newValue)
columnIndex = columnIndex + 1
print '\t'.join(outputs)
if __name__ == "__main__":
main(sys.argv[1:])
Hive和Python
Python可以通过HiveQL TRANSFORM语句从Hive用作UDF。例如,以下HiveQL调用存储在streaming.py文件中的Python脚本。
基于Linux的HDInsight
添加文件wasb:///streaming.py;
SELECT TRANSFORM (clientid, devicemake, devicemodel)
USING 'streaming.py' AS
(clientid string, phoneLable string, phoneHash string)
FROM hivesampletable
ORDER BY clientid LIMIT 50;
基于Windows的HDInsight
添加文件wasb:///streaming.py;
SELECT TRANSFORM (clientid, devicemake, devicemodel)
USING 'D:\Python27\python.exe streaming.py' AS
(clientid string, phoneLable string, phoneHash string)
FROM hivesampletable
ORDER BY clientid LIMIT 50;
这是这个例子的作用:
1.文件开头的add file语句将streaming.py文件添加到分布式缓存中,因此群集中的所有节点都可以访问它。
2. SELECT TRANSFORM ... USING语句从hivesampletable中选择数据,并将clientid,devicemake和devicemodel传递给streaming.py脚本。
3. AS子句描述了从streaming.py
返回的字段这里是HiveQL示例使用的streaming.py文件。
#!/usr/bin/env python
import sys
import string
import hashlib
while True:
line = sys.stdin.readline()
if not line:
break
line = string.strip(line, "\n ")
clientid, devicemake, devicemodel = string.split(line, "\t")
phone_label = devicemake + ' ' + devicemodel
print "\t".join([clientid, phone_label, hashlib.md5(phone_label).hexdigest()])
由于我们正在使用流式传输,因此该脚本必须执行以下操作:
1.从STDIN读取数据。这是通过在此示例中使用sys.stdin.readline()来完成的。
2.使用string.strip(line," \ n")删除尾随换行符,因为我们只需要文本数据而不是行尾指示符。
3.进行流处理时,单行包含每个值之间带有制表符的所有值。所以string.split(line," \ t")可以用来分割每个标签的输入,只返回字段。
4.处理完成后,输出必须作为单行写入STDOUT,每个字段之间有一个制表符。这是通过使用print" \ t" .join([clientid,phone_label,hashlib.md5(phone_label).hexdigest()])来实现的。
5.这一切都发生在while循环中,这将重复直到没有读取行,此时break退出循环并且脚本终止。
除此之外,脚本只是连接devicemake和devicemodel的输入值,并计算连接值的哈希值。非常简单,但它描述了从Hive调用的任何Python脚本应该如何工作的基础知识:循环,读取输入直到没有更多,在选项卡中分开输入的每一行,处理,写一行制表符分隔输出。