在 Ubuntu 上将 Python ODBC 与 Cloudera Impala ODBC driver 一起使用时出现 ParseException 语法错误
ParseException Syntax error when using Python ODBC with Cloudera Impala ODBC driver on Ubuntu
我们在 AWS EC2 实例 (Amazon Linux) 上有一个 Python 3.7 应用程序 运行,它针对 Cloudera Impala 服务执行 SQL 查询使用 pyodbc (4.0.27) 和 Cloudera Impala ODBC driver(使用 ClouderaImpalaODBC-2.6.5.rpm 安装)。此应用程序已 运行 成功多年。
我目前正在尝试在 Docker 容器 运行 Ubuntu 18.04.4 LTS 中获取应用程序 运行,但遇到以下错误时遇到问题运行 即使是最基本的查询(例如 SELECT 'HELLO'
):
Error: ('HY000', '[HY000] [Cloudera][ImpalaODBC] (110) Error while executing a query in Impala: [HY000] : ParseException: Syntax error in line 1:\n\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n^\nEncountered: Unexpected character\nExpected: ALTER, COMMENT, COMPUTE, COPY, CREATE, DELETE, DESCRIBE, DROP, EXPLAIN, GRANT, INSERT, INVALIDATE, LOAD, REFRESH, REVOKE, SELECT, SET, SHOW, TRUNCATE, UPDATE, UPSERT, USE, VALUES, WITH\n\nCAUSED BY: Exception: Syntax error\n\x00\u6572\u3a64\u5520\u656e\u7078\u6365\u6574\u2064\u6863\u7261\u6361\u6574\u0a72 (110) (SQLExecDirectW)')"}
不用说这看起来像是字符串编码问题。
一些上下文管理:
- 两个系统(亚马逊 Linux / Ubuntu)上的 python 代码是相同的
- 两个系统上的 Impala ODBC driver 安装具有相同的版本 (2.6.5); Ubuntu 的 Impala ODBC driver 直接从 Cloudera 网站下载 (https://www.cloudera.com/downloads/connectors/impala/odbc/2-6-5.html)
- Impala ODBC 连接参数除了 OS 特定项目外是相同的:
- "HOST": "[主机]"
- “端口”:21050
- "数据库": "[数据库]
- "UID": "[用户名]"
- "PWD": "[密码]"
- "Driver": "{/opt/cloudera/impalaodbc/lib/64/libclouderaimpalaodbc64.so}"
- “使用SASL”:1
- "AuthMech": 3
- "SSL": 1
- “CAIssuedCertNamesMismatch”:1
- “TrustedCerts”:“[path_to_certs_file]”
- “TSaslTransportBufSize”:1000
- “RowsFetchedPerBlock”:10000
- “套接字超时”:0
- “字符串列长度”:32767
- “UseNativeQuery”:0
- 应用程序似乎成功连接到 Impala,因为调用
pyodbc.connect(**config, autocommit=True)
或从连接获取光标时没有错误(已尝试使用无效的凭据来确保,并获得通常的信用错误时的连接错误)。错误消息的详细信息表明正在使用正确的 ODBC driver
我尝试为 Impala ODBC driver 参数“DriverManagerEncoding”设置不同的值,例如“UTF-16”、“UTF-32”完全有它(亚马逊 Linux 设置就是这种情况)但总是得到同样的错误。
我还尝试在两个系统上使用 odbclinux 工具 isql 尝试以这种方式进行故障排除;能够从 Amazon Linux 系统成功连接,但无法在 Ubuntu 上连接 - 始终得到以下信息(不确定这是否相关或其他问题):
iusql -v [DSN]
[unixODBC][
[ISQL]ERROR: Could not SQLDriverConnect
找到了罪魁祸首 - /opt/cloudera/impalaodbc/lib/64/cloudera.impalaodbc.ini
中的设置 DriverManagerEncoding
:
[Driver]
## - Note that this default DriverManagerEncoding of UTF-32 is for iODBC.
## - unixODBC uses UTF-16 by default.
## - If unixODBC was compiled with -DSQL_WCHART_CONVERT, then UTF-32 is the correct value.
## Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC
## - SimbaDM can be used with UTF-8 or UTF-16.
## The DriverUnicodeEncoding setting will cause SimbaDM to run in UTF-8 when set to 2 or UTF-16 when set to 1.
DriverManagerEncoding=UTF-32
ErrorMessagesPath=/opt/cloudera/impalaodbc/ErrorMessages/
LogLevel=0
LogPath=
SwapFilePath=/tmp
## - Uncomment the ODBCInstLib corresponding to the Driver Manager being used.
## - Note that the path to your ODBC Driver Manager must be specified in LD_LIBRARY_PATH (LIBPATH for AIX).
## - Note that AIX has a different format for specifying its shared libraries.
# Generic ODBCInstLib
# iODBC
# ODBCInstLib=libiodbcinst.so
# SimbaDM / unixODBC
#ODBCInstLib=libodbcinst.so
# AIX specific ODBCInstLib
# iODBC
#ODBCInstLib=libiodbcinst.a(libiodbcinst.so.2)
# SimbaDM
#ODBCInstLib=libodbcinst.a(odbcinst.so)
# unixODBC
ODBCInstLib=libodbcinst.a(libodbcinst.so.1)
此文件是作为驱动程序安装的一部分自动生成的。请注意关于 iODBC 与 unixODBC 的评论——我们只安装了后者。
一旦我注释掉该配置,我们的 python 应用程序就可以运行了。它还修复了 iusql
(这是 unixODBC 安装的一部分)的问题。
奖金内容:
我也遇到了 iqsl
(不是 iusql
)的问题 - 正在为命令 isql -v [DSN]
:
获取此 error/output
[S1000][unixODBC][Cloudera][ODBC] (11560) Unable to locate SQLGetPrivateProfileString function.
[ISQL]ERROR: Could not SQLConnect
该错误与同一 ini
文件中的配置参数 ODBCInstLib
有关。一旦我将它从默认 libodbcinst.a(libodbcinst.so.1)
更改为 /usr/lib/x86_64-linux-gnu/libodbcinst.so
它就起作用了。找到答案就在这个post里面,居然帮我解决了原来的问题:
Can't connect to snowflake via unixODBC. Error: [S1000][unixODBC][Snowflake][ODBC] (11560) Unable to locate SQLGetPrivateProfileString function
我们在 AWS EC2 实例 (Amazon Linux) 上有一个 Python 3.7 应用程序 运行,它针对 Cloudera Impala 服务执行 SQL 查询使用 pyodbc (4.0.27) 和 Cloudera Impala ODBC driver(使用 ClouderaImpalaODBC-2.6.5.rpm 安装)。此应用程序已 运行 成功多年。
我目前正在尝试在 Docker 容器 运行 Ubuntu 18.04.4 LTS 中获取应用程序 运行,但遇到以下错误时遇到问题运行 即使是最基本的查询(例如 SELECT 'HELLO'
):
Error: ('HY000', '[HY000] [Cloudera][ImpalaODBC] (110) Error while executing a query in Impala: [HY000] : ParseException: Syntax error in line 1:\n\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\n^\nEncountered: Unexpected character\nExpected: ALTER, COMMENT, COMPUTE, COPY, CREATE, DELETE, DESCRIBE, DROP, EXPLAIN, GRANT, INSERT, INVALIDATE, LOAD, REFRESH, REVOKE, SELECT, SET, SHOW, TRUNCATE, UPDATE, UPSERT, USE, VALUES, WITH\n\nCAUSED BY: Exception: Syntax error\n\x00\u6572\u3a64\u5520\u656e\u7078\u6365\u6574\u2064\u6863\u7261\u6361\u6574\u0a72 (110) (SQLExecDirectW)')"}
不用说这看起来像是字符串编码问题。
一些上下文管理:
- 两个系统(亚马逊 Linux / Ubuntu)上的 python 代码是相同的
- 两个系统上的 Impala ODBC driver 安装具有相同的版本 (2.6.5); Ubuntu 的 Impala ODBC driver 直接从 Cloudera 网站下载 (https://www.cloudera.com/downloads/connectors/impala/odbc/2-6-5.html)
- Impala ODBC 连接参数除了 OS 特定项目外是相同的:
- "HOST": "[主机]"
- “端口”:21050
- "数据库": "[数据库]
- "UID": "[用户名]"
- "PWD": "[密码]"
- "Driver": "{/opt/cloudera/impalaodbc/lib/64/libclouderaimpalaodbc64.so}"
- “使用SASL”:1
- "AuthMech": 3
- "SSL": 1
- “CAIssuedCertNamesMismatch”:1
- “TrustedCerts”:“[path_to_certs_file]”
- “TSaslTransportBufSize”:1000
- “RowsFetchedPerBlock”:10000
- “套接字超时”:0
- “字符串列长度”:32767
- “UseNativeQuery”:0
- 应用程序似乎成功连接到 Impala,因为调用
pyodbc.connect(**config, autocommit=True)
或从连接获取光标时没有错误(已尝试使用无效的凭据来确保,并获得通常的信用错误时的连接错误)。错误消息的详细信息表明正在使用正确的 ODBC driver
我尝试为 Impala ODBC driver 参数“DriverManagerEncoding”设置不同的值,例如“UTF-16”、“UTF-32”完全有它(亚马逊 Linux 设置就是这种情况)但总是得到同样的错误。
我还尝试在两个系统上使用 odbclinux 工具 isql 尝试以这种方式进行故障排除;能够从 Amazon Linux 系统成功连接,但无法在 Ubuntu 上连接 - 始终得到以下信息(不确定这是否相关或其他问题):
iusql -v [DSN]
[unixODBC][
[ISQL]ERROR: Could not SQLDriverConnect
找到了罪魁祸首 - /opt/cloudera/impalaodbc/lib/64/cloudera.impalaodbc.ini
中的设置 DriverManagerEncoding
:
[Driver]
## - Note that this default DriverManagerEncoding of UTF-32 is for iODBC.
## - unixODBC uses UTF-16 by default.
## - If unixODBC was compiled with -DSQL_WCHART_CONVERT, then UTF-32 is the correct value.
## Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC
## - SimbaDM can be used with UTF-8 or UTF-16.
## The DriverUnicodeEncoding setting will cause SimbaDM to run in UTF-8 when set to 2 or UTF-16 when set to 1.
DriverManagerEncoding=UTF-32
ErrorMessagesPath=/opt/cloudera/impalaodbc/ErrorMessages/
LogLevel=0
LogPath=
SwapFilePath=/tmp
## - Uncomment the ODBCInstLib corresponding to the Driver Manager being used.
## - Note that the path to your ODBC Driver Manager must be specified in LD_LIBRARY_PATH (LIBPATH for AIX).
## - Note that AIX has a different format for specifying its shared libraries.
# Generic ODBCInstLib
# iODBC
# ODBCInstLib=libiodbcinst.so
# SimbaDM / unixODBC
#ODBCInstLib=libodbcinst.so
# AIX specific ODBCInstLib
# iODBC
#ODBCInstLib=libiodbcinst.a(libiodbcinst.so.2)
# SimbaDM
#ODBCInstLib=libodbcinst.a(odbcinst.so)
# unixODBC
ODBCInstLib=libodbcinst.a(libodbcinst.so.1)
此文件是作为驱动程序安装的一部分自动生成的。请注意关于 iODBC 与 unixODBC 的评论——我们只安装了后者。
一旦我注释掉该配置,我们的 python 应用程序就可以运行了。它还修复了 iusql
(这是 unixODBC 安装的一部分)的问题。
奖金内容:
我也遇到了 iqsl
(不是 iusql
)的问题 - 正在为命令 isql -v [DSN]
:
[S1000][unixODBC][Cloudera][ODBC] (11560) Unable to locate SQLGetPrivateProfileString function.
[ISQL]ERROR: Could not SQLConnect
该错误与同一 ini
文件中的配置参数 ODBCInstLib
有关。一旦我将它从默认 libodbcinst.a(libodbcinst.so.1)
更改为 /usr/lib/x86_64-linux-gnu/libodbcinst.so
它就起作用了。找到答案就在这个post里面,居然帮我解决了原来的问题:
Can't connect to snowflake via unixODBC. Error: [S1000][unixODBC][Snowflake][ODBC] (11560) Unable to locate SQLGetPrivateProfileString function