SQLAlchemy 通过 cloudera ODBC DSN 访问 Impala 数据库时出现问题

问题描述 投票:0回答:2

我正在尝试通过 SQLAlchemy 访问 Impala DB - 我已经配置了一个 DSN,允许我在直接使用 pyodbc 时连接到数据库。

但是,当使用 SQLAlchemy 时,我收到错误:

在 DSN 中使用名为 datamart_x 的数据库时:

pyodbc.Error: ('HY000', '[HY000] [Cloudera][ImpalaODBC] (370) 查询 查询执行期间发生分析错误:[HY000]: AnalysisException:datamart_x.schema_name() 数据库未知 数据集市_x。目前该数据库有 0 个功能。 (370) (SQLExecDirectW)')

sqlalchemy.exc.DBAPIError: (pyodbc.Error) ('HY000', '[HY000] [Cloudera][ImpalaODBC] (370) 期间发生查询分析错误 查询执行:[HY000] : AnalysisException: datamart_x.schema_name() 数据库 datamart_x 未知。目前该数据库有 0 个功能。 (370) (SQLExecDirectW)') [SQL: SELECT schema_name()]

这不是权限问题 - 因为我可以使用相同的 DSN 通过 pyodbc 直接连接到数据库。

我怀疑问题出在 SQL 语句中:访问 SQLAlchemy 引擎时执行的 SELECT schema_name() (例如,在我的情况下使用 pandas read_sql)

如果有连接参数可以让它工作,有什么想法吗?

下面是我用来创建 SQLAlchemy 引擎的代码

connection_string = 'mssql+pyodbc://DataLake'
SQL = 'SHOW DATABASES'
args = {'autocommit': True}
engine = create_engine(connection_string, connect_args=args)
df = pd.read_sql(SQL, engine)

亲切的问候, 恩斯特

尝试了不同类型的连接字符串。

更新 为 sqlalchemy 模块启用日志记录(如下): 这似乎证实了我的怀疑 - 作为 SELECT schema_name() 但是我仍然不知道如何阻止 sqlalchemy 运行这个 sql 语句。

INFO:sqlalchemy.engine.Engine:SELECT CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR)
INFO:sqlalchemy.engine.Engine:[raw sql] ()
INFO:sqlalchemy.engine.Engine:ROLLBACK
INFO:sqlalchemy.engine.Engine:SELECT schema_name()
INFO:sqlalchemy.engine.Engine:[generated in 0.00042s] ()
INFO:sqlalchemy.engine.Engine:ROLLBACK
sqlalchemy odbc pyodbc cloudera impala
2个回答
0
投票

您正在尝试使用

mssql+pyodbc://
,这是 Microsoft SQL Server 的方言。您需要使用专门针对 Impala 的方言。使用示例可以在这里找到:

https://github.com/cloudera/impyla/blob/master/impala/tests/test_sqlalchemy.py


0
投票

下面的代码现在可以使用 Gord Thompson 的输入来工作

from sqlalchemy import create_engine
from impala.dbapi import connect
from impala.sqlalchemy import ImpalaDialect
from getpass import getpass
import pandas as pd

my_host = 'impalahost.com'
my_user = '[email protected]'
my_pass = getpass('The password please : ')
SQL = 'SHOW TABLES'

imp_conn = connect(host=my_host, port=21050, user=my_user, password=my_pass,
               use_ssl=True, auth_mechanism='PLAIN', database='default')


engine = create_engine('impala://', creator=lambda: imp_conn, echo=True)
conn = engine.connect()
df = pd.read_sql(SQL, conn)
print(df.head(15))
© www.soinside.com 2019 - 2024. All rights reserved.