使用webpy时为什么中文乱码但使用MySQLdb时是正常的?

eas*_*son 6 python web.py mysql-python

我在mysql中创建一个数据库,并使用webpy构建我的Web服务器.

但是,当webpy和MySQLdb分别使用它们来访问数据库时,中文字符对于它来说是如此奇怪.

以下是我的问题:

我的表t_test(utf8数据库):

id     name
1      ??
Run Code Online (Sandbox Code Playgroud)

"测试"的utf8代码是:\ xe6\xb5\x8b\xe8\xaf\x95

当使用MySQLdb做"选择"这样:

    c=conn.cursor()
    c.execute("SELECT * FROM t_test")
    items = c.fetchall()
    c.close()
    print "items=%s, name=%s"%(eval_items, eval_items[1])
Run Code Online (Sandbox Code Playgroud)

结果是正常的,它打印:

    items=(127L, '\xe6\xb5\x8b\xe8\xaf\x95'), name=??
Run Code Online (Sandbox Code Playgroud)

但是当我使用webpy做同样的事情时:

    db = web.database(dbn='mysql', host="127.0.0.1", 
             user='test', pw='test', db='db_test', charset="utf8")
    eval_items=db.select('t_test')
    comment=eval_items[0].name
    print "comment code=%s"%repr(comment)
    print "comment=%s"%comment.encode("utf8")
Run Code Online (Sandbox Code Playgroud)

中文出现乱码,打印结果为:

    comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022'
    comment=??????€
Run Code Online (Sandbox Code Playgroud)

我知道webpy的数据库也依赖于MySQLdb,但对于这两种方式它是如此不同.为什么?

顺便说一句,由于上面的原因,我可以直接使用MySQLdb来解决我的汉字乱码问题,但它丢失了表中的列名 - 它太不合适了.我想知道如何用webpy解决它?

jsb*_*eno 1

事实上,一些非常错误的事情正在发生——\nas你在评论中所说的,unicode repr。“\xe6\xb5\x8b\xe8\xaf\x95”的字节是 E6B5 8BE8 AF95 -\n它适用于我的 utf-8 终端:

\n\n
>>> d\n\'\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\'\n>>> print d\n\xe6\xb5\x8b\xe8\xaf\x95\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是看看你的“comment”unicode 对象上的字节:

\n\n
comment code=u\'\\xe6\\xb5\\u2039\\xe8\\xaf\\u2022\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着您的内容的一部分是注释的 utf-8 字节 \n(表示为“\\xYY”的字符,部分编码为 Unicode 点\n(用 \\uYYYY 表示的字符) - 这表示严重的垃圾。

\n\n

MySQL 有一些正确解码(utf-8 或其他)编码文本的方法 - 其中之一是将正确的“字符集”参数传递给连接。但你已经这么做了——

\n\n

您可以做的一种尝试是向连接传递选项use_unicode=False -\n 并在您自己的代码中解码 utf-8 字符串。

\n\n
db = web.database(dbn=\'mysql\', host="127.0.0.1", \n         user=\'test\', pw=\'test\', db=\'db_test\', charset="utf8", use_unicode=False)\n
Run Code Online (Sandbox Code Playgroud)\n\n

检查用于连接此参数和您可能尝试的其他参数的选项:

\n\n

http://mysql-python.sourceforge.net/MySQLdb.html

\n\n

不管如何让它正常工作,根据上面的提示,我为您找到了一个解决方法 - 看起来 Unicode 字符(不是 unicode 对象中的 utf-8 原始字节)\n 您的编码字符串被编码为以下之一:这些编码:\n("cp1258"、"cp1252"、"palmos"、"cp1254")

\n\n

其中,cp1252 几乎与“latin1”相同 - 这是 MySQL 使用的默认字符集\n如果它在连接中没有获取“charset”参数。但这不仅仅是 web2py 不将其传递到数据库的问题,因为你得到了损坏的字符,而不仅仅是错误的编码 - 这就好像 web2py 来回编码和解码你的字符串,并忽略编码错误

\n\n

从所有这些编码中,我可以检索原始的“\xe6\xb5\x8b\xe8\xaf\x95”字符串,作为 utf-8 字节字符串,例如:

\n\n
comment = comment.encode("cp1252", errors="ignore")\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,放置这一行现在可能对您有用,但是用 unicode 进行猜测永远不会好 -\nproepr 的事情是缩小 web2py 的范围,首先为您提供那些半解码的 utf-8 字符串,然后使它停在那里。

\n\n

更新

\n\n

我在这里检查-这就是发生的情况-\'\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\'从mysql读取正确的utf-8字符串,然后将其传递给您之前,(在use_unicode = True的情况下)0-这些字节正在被解码,就好像它们是“cp1252” " - 这会产生不正确的u\'\\xe6\\xb5\\u2039\\xe8\\xaf\\u2022\'unicode。\xc2\xa0这可能是一个web2py错误,比如,它没有将你的“charset=utf8”\xc2\xa0参数传递给实际连接。当您设置“use_unicode=False”而不是给您原始字节时,\xc2\xa0it 显然会选择不正确的 unicode,使用“utf-8”对其进行编码 - 这会产生您在\'\\xc3\\xa6\\xc2\\xb5\\xe2\\x80\\xb9\\xc3\\xa8\\xc2\\xaf\\xe2\\x80\\xa2\'下面评论的 \n 序列(甚至是更不正确)。

\n\n

总而言之,我上面提到的解决方法似乎是检索原始正确字符串的唯一方法 - 也就是说,如果给出错误的 unicode,那么u\'\\xe6\\xb5\\u2039\\xe8\\xaf\\u2022\'.encode("cp1252", errors="ignore")- 也就是说,缺少 \n做一些其他事情来设置数据库连接(或如果可能的话,也许更新 web2py 或 mysql 驱动程序)

\n\n

** 更新 2 **\n我进一步检查了 web2py 文件本身中的代码dal.py- 默认情况下它尝试将连接设置为 utf-8 - 但看起来它会尝试 MySQLdb 和 pymysql 驱动程序 - 如果你都安装了尝试卸载pymysql,只留下MySQLdb。

\n