使用python在Windows上连接hive

impyla连接hive

我这里使用的python版本为python3.8.1,连接hive需要以下的包。

pip install pure-sasl
pip install thrift_sasl==0.2.1 --no-deps
pip install thrift==0.9.3
以上三个包安装没有任何问题,直接pip install即可

pip install thriftpy==0.3.9
这个包安装也是可以直接pip install
只是在安装过程中会显示:ERROR: thrift-sasl 0.2.1 requires sasl>=0.2.1, which is not installed.
但是不用管,忽略它即可

然后安装一个叫做,bitarray的包。但由于它是使用C扩展编写的,在Windows上安装会报出gcc编译错误。可以下载vscode,但是比较麻烦,推荐的办法是进入https://www.lfd.uci.edu/~gohlke/pythonlibs/进行下载对应python版本的bitarray,进行安装

最后pip install impyla,安装的时候叫impyla,但是使用的时候是impala。

from impala.dbapi import connect

conn = connect(host='47.94.174.89', 
               port=10000, 
               database="default", 
               auth_mechanism='PLAIN')
cursor = conn.cursor()
cursor.execute('select * from girls')
print(cursor.fetchall())
# 执行上面代码会报出如下错误:
"""
Traceback (most recent call last):
  File "D:/satori/1.py", line 14, in <module>
    conn = connect(host='47.94.174.89', port=10000, database="default", auth_mechanism='PLAIN')
  File "C:\python38\lib\site-packages\impala\dbapi.py", line 144, in connect
    service = hs2.connect(host=host, port=port,
  File "C:\python38\lib\site-packages\impala\hiveserver2.py", line 825, in connect
    transport.open()
  File "C:\python38\lib\site-packages\thrift_sasl\__init__.py", line 75, in open
    self._send_message(self.START, chosen_mech)
  File "C:\python38\lib\site-packages\thrift_sasl\__init__.py", line 94, in _send_message
    self._trans.write(header + body)
TypeError: can't concat str to bytes
"""

根据提示信息:我们进入thrift_sasl模块下的__init__.py中,找到第94行。

# 值得一提的是,python中的缩进应该是四个空格,但是thrift_sasl用的两个空格,不过不影响
  def _send_message(self, status, body):
    header = struct.pack(">BI", status, len(body))
    self._trans.write(header + body)
    self._trans.flush()

  # 我们看到报错的原因是header + body、因为字符串和字节无法相加
  # 将上面代码改成如下
  def _send_message(self, status, body):
    header = struct.pack(">BI", status, len(body))
    if isinstance(body, str):
        body = bytes(body, encoding="utf-8")
    self._trans.write(header + body)
    self._trans.flush()

然后重新执行,成功获取数据。

from impala.dbapi import connect

conn = connect(host='47.94.174.89', port=10000, database="default", auth_mechanism='PLAIN')
cursor = conn.cursor()
cursor.execute('select * from girls')
print(cursor.fetchall())  # [(1, 'satori'), (2, 'mashiro')]

我个人到此就执行成功了,按照上述方法安装应该能够正常访问,但是你也可能还会报出如下错误。

"""
ThriftParserError: ThriftPy does not support generating module with path in protocol 'c'
"""
# 如果报出上面错误,那么进入site-packages\thriftpy\parser\parser.py
# 找到第488行,应该会看到一个条件语句,如下:
    if url_scheme == '':
        with open(path) as fh:
            data = fh.read()
    elif url_scheme in ('http', 'https'):
        data = urlopen(path).read()
    else:
        raise ThriftParserError('ThriftPy does not support generating module '
                                'with path in protocol \'{}\''.format(
                                    url_scheme))

"""
将
if url_scheme == '':
改成
if url_scheme == '' or len(url_scheme) == 1:
即可
"""

pyhive连接hive(局限性非常大)

首先impyla和pyhive在某些包上存在版本不兼容的问题,在安装的时候最好二者选其一(但是不推荐在Windows上使用pyhive)。因此在安装pyhive的时候,就当自己没有安装过impyla

安装sasl,这个包和上面的bitarray一样,都必须去上面指定的网站去下载,然后安装。但是这个包最高支持python3.7,正好为了和impyla区分,这里使用python3.6进行安装。安装完sasl之后,我们还需要安装一个thrift(安装pyhive的时候会自动安装),但是它要求的版本大于等于0.10.0。而impyla要求的是0.9.3,所以如果你安装了0.9.3的thrift,那么需要pip uninstall thrift将其卸载掉。

然后直接pip install pyhive[hive]即可,会自动将依赖下载下来

"""
注意:必须是pip install pyhive[hive]
如果是pip install pyhive的话,那么会有些关联的包装不上,在执行的时候会报如下错误
ImportError: cannot import name 'TFrozenDict' from 'thrift.Thrift' 
"""
from pyhive import hive
conn = hive.Connection(host='47.94.174.89', 
                       port=10000, 
                       database='default')
cursor = conn.cursor()
cursor.execute('select * from girls')
print(cursor.fetchall())
# 执行的时候会报出如下错误
"""
thrift.transport.TTransport.TTransportException: Could not start SASL: b'Error in sasl_client_start (-4) SASL(-4): no mechanism available: Unable to find a callback: 2'
"""
# 在linux上可以通过yum install cyrus-sasl-plain  cyrus-sasl-devel  cyrus-sasl-gssapi解决

这是sasl不支持Windows机型所导致的,我们可以将auth改成NOSASL。

from pyhive import hive
conn = hive.Connection(host='47.94.174.89', 
                       port=10000, 
                       database='default', 
                       auth="NOSASL")
cursor = conn.cursor()
cursor.execute('select * from girls')
print(cursor.fetchall())
# 但是这样又会报出如下错误
"""
thrift.transport.TTransport.TTransportException: TSocket read 0 bytes
"""

需要同时要求,hive的hive-site.xml中增加如下配置

<property>
    <name>hive.server2.authentication</name>
    <value>NOSASL</value>
</property>

将hive中的认证给修改掉,所以才说Windows上使用pyhive的局限性非常大,因为它要求服务器上的hive不能使用认证,但是服务器上的hive一般都是使用Kerberos认证的。

from pyhive import hive
conn = hive.Connection(host='47.94.174.89', 
                       port=10000, 
                       database='default', 
                       auth="NOSASL")
cursor = conn.cursor()
cursor.execute('select * from girls')
print(cursor.fetchall())  # [(1, 'satori'), (2, 'mashiro')]

所以Windows上连接hive推荐impyla,不建议使用pyhive

猜你喜欢

转载自www.cnblogs.com/traditional/p/12534719.html