【问题标题】:How to Connect to Hive via pyhive from Windows如何从 Windows 通过 pyhive 连接到 Hive
【发布时间】:2021-11-27 22:07:32
【问题描述】:

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

(pyhive-test) C:\dev\sandbox\pyhive-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:\Users\harnerd\Anaconda3\envs\pyhive-test\lib\site-packages\pyhive\hive.py", line 192, in __init__
    self._transport.open()
  File "C:\Users\harnerd\Anaconda3\envs\pyhive-test\lib\site-packages\thrift_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 沙盒 VM,HiveServer2 身份验证设置为“无”。

客户端是 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

这个错误是什么意思?如果有一些关于如何从 python 配置和使用 SASL 的文档肯定会很好 - 如果有的话,我想知道它。

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

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

self.mechanism 是“普通”; chosen_mechinitial_response 是空字符串 ('')。 ret 为 False,导致抛出异常。

我知道我不是唯一一个试图在 Windows 上使用 pyhive 连接到 Hive 的人——这个人 (SASL error when trying to connect to hive(hue) by python from my PC - Windows10) 是,但他的“解决方案”——在他的 Windows 机器上安装 Ubuntu 作为 VM——不是为我工作。

【问题讨论】:

  • Pyodbc 运行顺畅。您有兴趣了解吗?
  • @KoushikRoy - 当然可以。 pyodbc 也可以与 kerberized Hives 一起使用吗?在 Linux 系统上呢?我添加了一些关于如何在我的问题中使用此代码的额外上下文。
  • 我认为它确实适用于 Kerberos 身份验证。它也可以在linux上运行。实际上,我们在使用 cloudera odbc 的 Windows 中编写代码,然后将代码移动到同样使用 cloudera odbc 的 linux 服务器上运行。现在,不是 100% 确定它是否适用于您的 odbc,但理论上它应该有效。
  • @KoushikRoy - 这听起来与我们的环境相似。您能否提供如何使用 pyodbc 进行连接的示例?

标签: python hive sasl pyhive


【解决方案1】:

长话短说,这个问题的答案是 PyHive 在 Windows 上根本不受支持。这是因为 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,因为所有必要的信息都是使用节俭传输传递的。不过需要注意的是 - 在注入 thrift 传输时,PyHive 断言 hostportauthkerberos_service_namepassword 不能具有除 None 之外的任何值。不幸的是,如果没有提供端口号,SQLAlchemy 会将默认的 Hive 端口 10000 分配给 port。解决方法是替换HiveDialect.create_connect_args方法,如下图:https://github.com/devinstevenson/pure-transport/issues/7。简单地继承 HiveDialect 类在这里不起作用,因为名称 HiveDialect 在 SQLAlchemy 的方言注册表中,不能简单地替换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多