如何在Windows环境下通过pyhive连接Hive



在过去的几天里,我一直在绞尽脑汁,试图用Python客户端在Windows上使用pyhive连接到Hive服务器。我是Hive的新手(pyhive也是如此),但我是一个相当有经验的Python开发人员。我总是得到以下错误:

(pyhive-test) C:devsandboxpyhive-test>python test.py
Traceback (most recent call last):
File "test.py", line 3, in <module>
conn = hive.Connection(host='192.168.1.196', port='10000', database='default', auth='NONE')
File "C:UsersharnerdAnaconda3envspyhive-testlibsite-packagespyhivehive.py", line 192, in __init__
self._transport.open()
File "C:UsersharnerdAnaconda3envspyhive-testlibsite-packagesthrift_sasl__init__.py", line 84, in open
raise TTransportException(type=TTransportException.NOT_OPEN,
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'

执行以下脚本:

from pyhive import hive
conn = hive.Connection(host='192.168.1.196', port='10000', database='default', auth='NONE')
cur = conn.cursor()
cur.execute('show tables')
data = cur.fetchall()
print(data)

HiveServer2实例是一个来自Cloudera的现成的HDP沙箱虚拟机,HiveServer2认证设置为"None"。

客户端是Windows 10上的Anaconda虚拟环境,Python为3.8.5,conda安装了以下包:

  • pyhive 0.6.1
  • sasl 0.2.1
  • 节俭0.13.0
  • thrift-sasl 0.4.2

现在我只是试图用上面的脚本连接到Hive,但最终我打算在Flask应用程序的SQLAlchemy中使用pyhive。换句话说:Flask ->Flask-SQLAlchemy→SQLAlchemy→pyhive。在生产环境中,Flask应用程序将由Cloudera Data Science Workbench(即某种Linux风格)托管,但将在Windows系统上开发(因此也必须运行)。

当然,我在这里看到了许多问题,在Cloudera的网站上,和GitHub有关Hive连接问题,如果有人拿枪指着我的头,我不得不说,从Windows客户端尝试这个可能是问题的一部分,因为这似乎不是一个很常见的事情。

No mechanism available

这个错误到底是什么意思?它肯定就好了如果有一些文档如何配置和使用SASL从python -如果有我想知道。

FWIW,导致错误的行在thrift_sasl/__init__.py:

ret, chosen_mech, initial_response = self.sasl.start(self.mechanism)

self.mechanismis 'PLAIN';chosen_mechinitial_response为空字符串(")。ret为False,导致抛出异常。

我知道我不是唯一一个试图在Windows上用pyhive连接到Hive的人-这个家伙(当试图从我的PC - Windows10连接到Hive (hue)时SASL错误)是,但他的"解决方案"-在他的Windows盒子上安装Ubuntu作为虚拟机-对我来说是行不通的。

长话短说,这个问题的答案是Windows不支持PyHive。这是由于PyHive使用sasl库进行Hive连接,sasl不仅难以在Windows上从源代码编译,而且似乎根本无法在Windows上工作。

关键是提供你自己的thrift_transport而不是依赖于PyHive来创建它。Devin Stevenson提供了另一种传输方式(https://github.com/devinstevenson/pure-transport),它在Windows上运行良好,应该也能在其他操作系统上运行(不过我还没有测试过)。他的repo提供了直接在Hive和SQLAlchemy中使用纯传输的示例。

在我的用例中,我在Flask应用程序中使用它与Flask- sqlalchemy。我注入thrift传输的方式是这样的:

from flask_sqlalchemy import SQLAlchemy
import puretransport
thrift_transport = puretransport.transport_factory(host='127.0.0.1',
port=10000,
username='a_user',
password='a_password')

class MySQLAlchemy(SQLAlchemy):
'''
Subclassing the standard SQLAlchemy class so we can inject our own thrift
transport which is needed to get pyhive to work on Windows
'''
def apply_driver_hacks(self, app, sa_url, options):
'''
If the current driver is for Hive, add our thrift transport
'''
if sa_url.drivername.startswith('hive'):
if 'connect_args' not in options:
options['connect_args'] = {'thrift_transport': thrift_transport}
return super(MySQLAlchemy, self).apply_driver_hacks(app, sa_url, options)
# later, in models.py...
db = MySQLAlchemy()
class AModelClass(db.Model):
__tablename__ = 'some_table'
id = db.Column(db.Integer, primary_key=True)
# etc...

在我的情况下,我使用我的Hive连接的URL是简单的形式hive:///{database_name},即:hive:///customers,因为所有必要的信息是使用节俭传输传递。需要注意的是——在注入节俭传输时,PyHive断言hostportauthkerberos_service_namepassword不能有None以外的值。不幸的是,如果没有提供端口号,SQLAlchemy将默认的Hive端口10000分配给port。解决方案是替换HiveDialect.create_connect_args方法,如下所示:https://github.com/devinstevenson/pure-transport/issues/7。简单地子类化HiveDialect类在这里不起作用,因为名称HiveDialect在SQLAlchemy的方言注册表中,不能简单地替换。

最新更新