我收到了这个错误信息
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 38: ordinal not in range(128)
当我尝试用Python执行任何sql查询时,如下面这样:
>>> import ibm_db
>>> conn = ibm_db.connect("sample","root","root")
>>> ibm_db.exec_immediate(conn, "select * from act")
我检查了默认编码,它似乎是'utf8':
^{pr2}$我还知道this线程,人们在讨论一个非常类似的问题。其中一条建议是:
Have you applied the required database PTFs (SI57014 and SI57015 for 7.1 and SI57146 and SI57147 for 7.2)? They are included as a distreq, so they should have been in the order with your PTFs, but won't be automatically applied.
但是,我不知道什么是数据库PTF以及如何应用它。需要帮助。在
另外,我用的是Windows10。在
编辑
这是我得到错误信息的方法:
>>> print(ibm_db.stmt_errormsg())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 38:
ordinal not in range(128)
但是当我在DB2 CLP
中运行同一个查询“select*from act”,就可以了。
这是驱动程序信息,我为什么要用Python运行这些代码:
if client:
print("DRIVER_NAME: string(%d) \"%s\"" % (len(client.DRIVER_NAME), client.DRIVER_NAME))
print("DRIVER_VER: string(%d) \"%s\"" % (len(client.DRIVER_VER), client.DRIVER_VER))
print("DATA_SOURCE_NAME: string(%d) \"%s\"" % (len(client.DATA_SOURCE_NAME), client.DATA_SOURCE_NAME))
print("DRIVER_ODBC_VER: string(%d) \"%s\"" % (len(client.DRIVER_ODBC_VER), client.DRIVER_ODBC_VER))
print("ODBC_VER: string(%d) \"%s\"" % (len(client.ODBC_VER), client.ODBC_VER))
print("ODBC_SQL_CONFORMANCE: string(%d) \"%s\"" % (len(client.ODBC_SQL_CONFORMANCE), client.ODBC_SQL_CONFORMANCE))
print("APPL_CODEPAGE: int(%s)" % client.APPL_CODEPAGE)
print("CONN_CODEPAGE: int(%s)" % client.CONN_CODEPAGE)
ibm_db.close(conn)
else:
print("Error.")
它打印:
DRIVER_NAME: string(10) "DB2CLI.DLL"
DRIVER_VER: string(10) "10.05.0007"
DATA_SOURCE_NAME: string(6) "SAMPLE"
DRIVER_ODBC_VER: string(5) "03.51"
ODBC_VER: string(10) "03.01.0000"
ODBC_SQL_CONFORMANCE: string(8) "EXTENDED"
APPL_CODEPAGE: int(1251)
CONN_CODEPAGE: int(1208)
True
编辑
我也试过了:
>>> cnx = ibm_db.connect("sample","root","root")
>>> query = "select * from act"
>>> query.encode('ascii')
b'select * from act'
>>> ibm_db.exec_immediate(cnx, query)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
>>> print(ibm_db.stmt_errormsg())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 38:
ordinal not in range(128)
如您所见,在本例中,我也得到了同样的错误消息。在
摘要
以下是我所有的尝试:
C:\Windows\system32>chcp
Active code page: 65001
C:\Windows\system32>python
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ibm_db
>>> cnx = ibm_db.connect("sample","root","root")
>>> ibm_db.exec_immediate(cnx, "select * from act")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
>>> print(ibm_db.stmt_errormsg())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 38: ordinal not in range(128)
>>> ibm_db.exec_immediate(cnx, b"select * from act")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: statement must be a string or unicode
>>> query = "select * from act"
>>> query = query.encode()
>>> ibm_db.exec_immediate(cnx, query)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: statement must be a string or unicode
>>> ibm_db.exec_immediate(cnx, "select * from act").decode('cp-1251')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
在这种情况下,使用一个utf8环境,使用一个ascii环境;我使用decode方法。在
好吧,这很正常,这不是ascii而是utf8字符串:你应该用utf8编码解码。在
^{pr2}$之后,您可能需要重新编码结果以写入或打印它们。在
问题是DB2服务器在配置输出中返回CP-1251(也称为Windows-1251)文本(由
APPL_CODEPAGE: int(1251)
证明)。Python(特别是交互式Python REPL)期望UTF-8或ASCII输出,因此这会导致问题。在解决方案是:
另外,您需要确保终端的文本编码设置为UTF-8。有关更改该设置的详细信息将取决于您使用的特定终端。因为您已经说过您正在使用
cmd
,所以适当的命令是chcp 65001
。在这里的问题是您的客户机代码(ibm_db)和DB2服务器之间不兼容。正如您在client code中看到的,查询的逻辑基本上是:
根据我们到目前为止的调查,您知道为查询传递的数据格式良好(因此不是步骤1)。查看步骤2中的错误路径,您将看到解释这些失败的简单错误消息。因此,您在第3步中失败了。在
在查询中引发了一个空异常,当您试图获取错误的详细信息时,您会得到另一个Unicode解码异常。这看起来像是ibm_db中的一个bug,或者是一个配置错误,这意味着您的DB2安装不兼容。那么我们怎么才能找出哪个。。。?在
与其他地方一样,基本上是用代码标记页面。所有ibm的db代码基本上都将字符串解释为ASCII(通过使用
StringOBJ_FromASCII
将其转换为pythonapi中的调用,这些api坚持接收ASCII字符,否则将抛出unicode异常)。在根据您的诊断,您可以通过安装/配置您的系统(客户机和DB2服务器)来使用美式英语来证明/反驳这个问题。这应该可以帮助您克服代码页的不兼容性,从而在这里找到真正的错误。在
如果查询确实是通过网络发出的,那么您可能只会得到一个显示从服务器返回的响应的网络跟踪。然而,基于你在日志中什么也没看到的事实,我不相信这会有任何结果。在
如果失败,您需要修补ibm_db代码来处理非ASCII内容—可以向维护人员提出错误报告,也可以自己尝试(如果您知道如何构建和调试C扩展)。在
相关问题 更多 >
编程相关推荐