如何使用pyodbc/unixODBC从python3中的Informix数据库连接选择数据

问题描述:

我在使用python3.5和pyodbc/unixODBC从Informix数据库表中选择数据时出现问题。如何使用pyodbc/unixODBC从python3中的Informix数据库连接选择数据

我有一点点PY文件(ifx.py),它的内容是:

import pyodbc 
db=pyodbc.connect('DSN=Test1') 
db.execute("SELECT * FROM customer ") 

,我得到一个错误:

pyodbc.Error: ('HY000', '[HY000] [Informix][Informix ODBC Driver]Invalid byte in codeset conversion input. (21000) (SQLExecDirectW)') 

所有的搜索,我已经做了一些暗示与LOCALE设置,但我检查,他们都设置相同:

CLIENT_LOCALE=en_US.819 
DB_LOCALE=en_US.819 
dbs_collate=en_US.819 

如果我使用unixODBC'isql'实用程序我ca n愉快地连接并且查询数据。

版本信息。

unixODBC.x86_64 0:2.2.14-14.el6 
pyodbc.version => '4.0.6' 
Linux => Red Hat Enterprise Linux Server release 6.8 
python3.5 => Python 3.5.3 
Database => IBM Informix Dynamic Server Version 12.10.FC6X5 
ClientSDK => IBM Informix CSDK Version 4.10, IBM Informix-ESQL Version 4.10.FC6 

环境变量ODBCINI指向/etc/odbc.ini。内容是:

[ODBC Data Sources] 
Test1=IBM INFORMIX ODBC DRIVER 
; 
; Define ODBC Database Driver's Below - Driver Configuration Section 
; 
[Test1] 
Driver=/opt/informix/lib/cli/iclis09b.so 
Description=IBM INFORMIX ODBC DRIVER 
Database=eunice 
LogonID= 
pwd= 
Servername=indika_test 
Port=9916 
CursorBehavior=0 
CLIENT_LOCALE=en_US.819 
DB_LOCALE=en_US.819 
TRANSLATIONDLL=/opt/informix/lib/esql/igo4a304.so 

/etc/odbcinst.ini内容:

[ODBC Drivers] 
IBM INFORMIX ODBC DRIVER=Installed 
[IBM INFORMIX ODBC DRIVER] 
Driver=/opt/informix/lib/cli/iclit09b.so 
Setup=/opt/informix/lib/cli/iclit09b.so 
APILevel=1 
ConnectFunctions=YYY 
DriverODBCVer=03.51 
FileUsage=0 
SQLLevel=1 
smProcessPerConnect=Y 

和ODBCINST -j输出

unixODBC 2.2.14 
DRIVERS............: /etc/odbcinst.ini 
SYSTEM DATA SOURCES: /etc/odbc.ini 
FILE DATA SOURCES..: /etc/ODBCDataSources 
USER DATA SOURCES..: /etc/odbc.ini 
SQLULEN Size.......: 8 
SQLLEN Size........: 8 
SQLSETPOSIROW Size.: 8 

预先感谢任何帮助或建议。

这可能是由于客户表中的多字节字符,无法从UTF8转换为Latin 1,ISO 8859-1。即使在CLIENT_LOCALE和DB_LOCALE中设置了相同的代码,ODBC客户端也会进行从UTF-8到8859的内部转换。如果有任何2字节字符(扩展ASCII字符255之外的字符),它们将不会转换为Latin-1客户。我会查看客户表中的数据并确定有问题的数据。

+0

感谢您的反馈意见,但我怀疑它没有数据在我的表中。我创建了一个3列的小桌子。通过unixODBC isql我可以选择数据: 'SQL> select * from jeff; + ----------- + --------- + ------------ + | _name | _code | _int | + ----------- + --------- + ------------ + | ABCDEFGHIJ | 12345678 | 123456789 | + ----------- + --------- + ------------ +' 通过python我得到相同的错误 – JeffP

+0

@JeffP做如果你在sqlite中创建一个小表,你会得到这种错误?换句话说:我们可以确定这是否是连接到此数据库或任何数据库的问题? – gregory

有可能(或可能)有一个Unicode编码不匹配。 在我的Debian系统上,python build(2.7和3.4)都使用UCS-4编码。你可以用这个命令来验证:

python3 -c “进口SYS;打印(sys.maxunicode < 66000 and'UCS2'or'UCS4' )”

一旦你找到了编码,你需要确认Informix odbc.ini文件具有相同的Unicode编码。在我的odbc.ini文件,

[ODBC]

;取消对以下行UNICODE连接

UNICODE = UCS-4

我希望这可以解决您的问题。

感谢您的回复。这是unicode不匹配。

db=pyodbc.connect('DSN=Test1') 
db.setdecoding(pyodbc.SQL_WCHAR, encoding='UTF-8') 
db.setdecoding(pyodbc.SQL_CHAR, encoding='UTF-8') 
db.setencoding(encoding='UTF-8') 

通过添加setencoding和setdecoding我能成功地选择数据形成的Informix数据库。