Python和IBM DB2:UnicodeDecodeError [英] Python and IBM DB2: UnicodeDecodeError

查看:63
本文介绍了Python和IBM DB2:UnicodeDecodeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到此错误消息

UnicodeDecodeError:"ascii"编解码器无法解码位置38的字节0xc8:序数不在范围(128)中

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 38: ordinal not in range(128)

当我尝试在Python中执行任何sql查询时,就像这样:

when I try to execute any sql query in Python, like this one:

>>> import ibm_db
>>> conn = ibm_db.connect("sample","root","root")
>>> ibm_db.exec_immediate(conn, "select * from act")

我检查了默认编码,它似乎是'utf8':

I checked default encoding and it seems to be 'utf8':

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

我也了解线程,人们正在讨论一个非常类似的问题.建议之一是:

I also know about this thread, where people are discussing quite a similar problem. One of the advices is:

您是否已应用所需的数据库PTF(7.1的为SI57014和SI57015,而7.2的为SI57146和SI57147)?它们作为离散值包含在内,因此它们应该与您的PTF保持一致,但不会自动应用.

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以及如何应用它.需要帮助.

However, I do not know what is database PTF and how to apply it. Need help.

PS.我正在使用Windows 10.

PS. I'm using Windows 10.

编辑

这是我收到错误消息的方式:

This is how I get my error message:

>>> 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中运行了以下代码:

But when I run the same query "select * from act" in DB2 CLP, then it's ok. And this is driver information, whcih I got running this code in 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)

如您所见,在这种情况下,我还会收到完全相同的错误消息.

As you can see, in this case I also get the very same error message.

摘要

下面是我的所有举动:

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

推荐答案

此处的内容是客户机代码(ibm_db)与DB2服务器之间的不兼容.如您在客户端代码中所见您查询的逻辑基本上是:

What you have here is an incompatibility between your client code (ibm_db) and the DB2 server. As you can see in the client code the logic for your query is basically:

  1. 提取并检查传入的参数(第4873至4918行).
  2. 为查询分配本机对象(最多4954个).
  3. 执行查询并解码结果(功能的其余部分).

根据到目前为止的调查,您知道为查询传递的数据格式正确(因此不是步骤1).查看步骤2中的错误路径,您将看到说明这些故障的简单错误消息.因此,您在步骤3中失败.

Based on our investigations so far, you know that the data you're passing in for the query is well-formed (and so it is not step 1). Looking at the error paths in step 2, you'd see simple error messages explaining these failures. You're therefore failing in step 3.

您将在查询上引发一个空异常,并且当您尝试获取错误的详细信息时,您会收到另一个Unicode解码异常.这看起来像是ibm_db中的错误或配置错误,这意味着您的DB2安装不兼容.那么我们如何找出哪个...?

You are getting an empty Exception raised on the query and when you try to get the details of the error you get another Unicode decoding Exception. This looks like either a bug in ibm_db or a configuration error that means your DB2 installation is not compatible. So how can we find out which...?

正如在其他地方标记的那样,该问题基本上与代码页有关.所有的ibm_db代码基本上都将字符串解释为ASCII(通过使用 StringOBJ_FromASCII 对其进行转换,从而将其映射为坚持接收ASCII字符的Python API的调用-否则将引发Unicode异常).

As flagged elsewhere, the issue is fundamentally to do with codepages. All the ibm_db code basically interprets strings as ASCII (by converting them with StringOBJ_FromASCII which maps down to calls into Python APIs that insist on receiving ASCII chars - and will throw unicode exceptions if not).

基于您的诊断,您可以尝试通过安装/配置两个系统(客户机和DB2服务器)以使用美国英语来证明/证明此问题.这样可以使您摆脱代码页不兼容的问题,从而在此处找到真正的错误.

Based on your diags, you could try to prove/disprove this problem, by installing/configuring both your systems (client and DB2 server) to use US English. This should get you past the codepage incompatibility to find the real error here.

如果查询实际上是通过网络发送的,则您可能只是获得网络跟踪,该跟踪显示了从服务器返回的响应.但是,基于您在日志中什么都没看到的事实,我不认为这会取得任何成果.

If the query is really going out over the network, you might just get a network trace that shows the response coming back from the server. However, based on the fact that you saw nothing in the logs, I'm not convinced this will bear any fruit.

您需要修补ibm_db代码以处理非ASCII内容失败-通过向维护者提出错误报告,或者自己尝试(如果您知道如何构建和调试C扩展)来进行尝试.

Failing that you need to patch the ibm_db code to handle non-ASCII content - either by raising a bug report with the maintainer or trying it yourself (if you know how to build and debug C extensions).

这篇关于Python和IBM DB2:UnicodeDecodeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆