之所以要使用pandas读取hive的数据,是在于pandas的数据处理能力很强,当然也可以使用sparksql处理,但如果要使用结果图表展示的话,建议还是使用pandas,当然如果上到集群的层面,sparksql是比较好的选择
废话少说,上代码
1. 安装依赖`
pip install pyhive
pip install thrift
pip install sasl
pip install thrift_sasl
如果你是就会发现sasl安装失败,如果你在windows平台上的话,这时候你需要到一个网站去下载专用于window的whl
https://www.lfd.uci.edu/~gohlke/pythonlibs/#sasl
然后切换到下载的目录下下进行安装
2.配置hive
做到这一步的朋友,算是已经事情成功了一半,但只是一半,pyhive连接hive是需要使用hiveserver2服务的。
"""Wraps a Thrift session"""
def __init__(
self,
host=None,
port=None,
scheme=None,
username=None,
database='default',
auth=None,
configuration=None,
kerberos_service_name=None,
password=None,
check_hostname=None,
ssl_cert=None,
thrift_transport=None
):
"""Connect to HiveServer2
如果没有配置tez引擎的朋友会非常崩溃,因为在hive3版本,使用hiveserver2服务必须先启动tez,本人由于没有配置tez,被搞得有些崩溃,不知道为什么启动不了,最后在hive日志里,看到tez启动失败,才知道启动hiveserver2前,除了必须启动hadoop和metastore的元数据服务,还需要启动tez
最后终于在深通广大的网友的博客找到一个配置
<!-- hive service2的执行引擎改为mapreduce -->
<property>
<name>hive.execution.engine</name>
<value>mr</value>
</property>
<!-- hiveserver2的高可用参数,开启此参数可以提高hiveserver2的启动速度 主要是这个配置-->
<property>
<name>hive.server2.active.passive.ha.enable</name>
<value>true</value>
</property>
当然如果你不是root用户的话,启动hiveserver2会产生一个(lin是我的用户名)
RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: lin is not allowed to impersonate lin
这时候就必须修改hadoop的配置了,在hadoop的core-site.xml的加入如下的配置
<property>
<name>hadoop.proxyuser.lin.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.lin.groups</name>
<value>*</value>
</property>
在hdfs-site.xml加入如下配置
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
3 重启服务
启动hadoop之后,启动hive的元数据服务在启动hiveserver2
bin/hive --service metastore
bin/hive --service hiveserver2
#测试连接成功
bin/beeline -u jdbc:hive2://hadoop102:10000 -n li
4.连接hive
from pyhive import hive
import pandas as pd
conn = hive.Connection(host='hadoop102', port=10000, database='hotel_detail', username="lin")
cursor = conn.cursor()
cursor.execute('select name ,new_price ,old_price from hotel_info limit 100')
# 这是使用python读取的方法
data = cursor.fetchall()
# 使用pandas 读取数据的方法
df = pd.read_sql("select name ,new_price ,old_price from hotel_info limit 100", conn)
print(data)