我們有一個 Python 3.7 應用程式在 AWS EC2 實體 (Amazon Linux) 上運行,該應用程式使用 pyodbc (4.0.27) 和 Cloudera Impala ODBC 驅動程式(使用 ClouderaImpalaODBC-2.6.5.rpm 安裝)對 Cloudera Impala 服務執行 SQL 查詢。這個應用程式已經成功運行了好幾年。
SELECT 'HELLO'我目前正在嘗試讓應用程式在運行 Ubuntu 18.04.4 LTS 的 Docker 容器中運行,但在運行最基本的查詢(例如)時遇到以下錯誤:
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)')"}
不用說,這看起來像是一個字串編碼問題。
一些背景關系內務管理:
- 兩個系統(Amazon Linux / Ubuntu)上的 python 代碼是相同的
- 兩個系統上的 Impala ODBC 驅動程式安裝具有相同的版本 (2.6.5);Ubuntu 的 Impala ODBC 驅動程式直接從 Cloudera 網站下載 ( https://www.cloudera.com/downloads/connectors/impala/odbc/2-6-5.html )
- Impala ODBC 連接引數是相同的,除了作業系統特定的專案:
- “主機”:“[主機]”
- “港口”:21050
- “資料庫”:“[資料庫]
- “UID”:“[用戶名]”
- “密碼”:“[密碼]”
- “驅動程式”:“{/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
- “使用本機查詢”:0
- 該應用程式似乎已成功連接到 Impala,因為沒有錯誤呼叫
pyodbc.connect(**config, autocommit=True)或從連接中獲取游標(已嘗試使用無效憑據來確保,并在憑據錯誤時獲得通常的連接錯誤)。錯誤訊息的詳細資訊表明正在使用正確的 ODBC 驅動程式
我嘗試使用 Impala ODBC 驅動程式引數“DriverManagerEncoding”的不同值,例如“UTF-16”、“UTF-32”或根本沒有它(Amazon Linux 設定就是這種情況)但總是得到同樣的錯誤。
我還嘗試在兩個系統上使用 odbclinux 工具 isql 來嘗試以這種方式進行故障排除;能夠從 Amazon Linux 系統成功連接,但無法在 Ubuntu 上連接 - 始終得到以下資訊(不確定這是否相關或其他問題):
iusql -v [DSN]
[unixODBC][
[ISQL]ERROR: Could not SQLDriverConnect
uj5u.com熱心網友回復:
DriverManagerEncoding找到了罪魁禍首 - 是設定/opt/cloudera/impalaodbc/lib/64/cloudera.impalaodbc.ini:
[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
ODBCInstLib該錯誤與同一ini檔案中的配置引數有關。一旦我將它從默認更改libodbcinst.a(libodbcinst.so.1)為/usr/lib/x86_64-linux-gnu/libodbcinst.so它作業。發現答案在這篇文章中,它實際上幫助解決了我最初的問題:
無法通過 unixODBC 連接到雪花。錯誤:[S1000][unixODBC][Snowflake][ODBC] (11560) 無法找到 SQLGetPrivateProfileString 函式
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/472129.html
