我在mysql中创建一个数据库,并使用webpy构建我的Web服务器。
但是,当webpy和MySQLdb分别使用它们来访问数据库时,对于中文字符来说很奇怪。
以下是我的问题:
我的表t_test(utf8数据库):
id name
1 测试
“测试”的utf8代码是:\ xe6 \ xb5 \ x8b \ xe8 \ xaf \ x95
使用MySQLdb进行“select”时这样:
c=conn.cursor()
c.execute("SELECT * FROM t_test")
items = c.fetchall()
c.close()
print "items=%s, name=%s"%(eval_items, eval_items[1])
结果正常,打印出来:
items=(127L, '\xe6\xb5\x8b\xe8\xaf\x95'), name=测试
但是当我使用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")
发生中文乱码,打印结果为:
comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022'
comment=忙碌鈥姑€
我知道webpy的数据库也依赖于MySQLdb,但这两种方式都有所不同。为什么呢?
顺便说一下,由于上面的原因,我可以直接使用MySQLdb来解决我的汉字乱码问题,但它丢失了表中的列名 - 它太不合适了。我想知道如何用webpy解决它?答案 0 :(得分:1)
确实发生了一些非常错误的事情 - 正如你在评论中所说,unicode repr。 “测试”的字节是E6B5 8BE8 AF95 - 这可以在我的utf-8终端上运行:
>>> d
'\xe6\xb5\x8b\xe8\xaf\x95'
>>> print d
测试
但请查看“comment”unicode对象上的字节:
comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022'
您的内容的含义部分是注释的utf-8字节 (字符表示为“\ xYY”,部分编码为Unicode点 (用\ uYYYY表示的chares) - 这表示严重的垃圾。
MySQL有一些捕获正确解码(utf-8或其他)编码 其中的文本 - 其中一个是传递一个适当的“charset”参数 连接。但你已经这样做了 -
您可以尝试的一种方法是将选项use_unicode=False
传递给连接 -
并在您自己的代码中解码utf-8字符串。
db = web.database(dbn='mysql', host="127.0.0.1",
user='test', pw='test', db='db_test', charset="utf8", use_unicode=False)
检查要连接的选项以及您可能尝试的其他参数:
http://mysql-python.sourceforge.net/MySQLdb.html
无论使用正确如何,通过上面的提示,我得到了一个解决方法 - 它看起来像Unicode字符(不是unicode对象中的utf-8原始字节) 在您编码的字符串中编码为以下编码之一: (“cp1258”,“cp1252”,“palmos”,“cp1254”)
其中,cp1252与“latin1”几乎相同 - 这是MySQL使用的默认字符集 如果它没有得到连接中的“charset”参数。但这不仅仅是一个问题 web2py没有将它传递给数据库,因为你得到了错误的字符,而不是 只是错误的编码 - 就好像web2py来回编码和解码你的字符串,并忽略编码错误
从所有这些编码中,我可以检索原始的“测试”字符串,作为utf-8字节字符串,例如:
comment = comment.encode("cp1252", errors="ignore")
所以,放置这一行可能对你有用,但猜测unicode永远不会好 - proepr的事情是缩小使web2py首先给你那些半解码的utf-8字符串,然后让它停在那里。
<强>更新强>
我在这里检查 - 这是发生了什么 - 从mysql读取正确的utf-8 '\xe6\xb5\x8b\xe8\xaf\x95'
字符串,然后在交付给你之前,(在use_unicode = True情况下)0-这些字节是被解码好像他们是“cp1252” - 这会产生不正确的u'\xe6\xb5\u2039\xe8\xaf\u2022'
unicode。它可能是一个web2py错误,例如,它没有将“charset = utf8”参数传递给实际连接。当您设置“use_unicode = False”而不是给出原始字节时,它显然选择了不正确的unicode,使用“utf-8”对其进行了编码 - 这会产生
你评论过的'\xc3\xa6\xc2\xb5\xe2\x80\xb9\xc3\xa8\xc2\xaf\xe2\x80\xa2'
序列(更不正确)。
总而言之,我上面提到的解决方法似乎是检索原始正确字符串的唯一方法 - 即,给定错误的unicode,执行u'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore")
- 即
做其他事情来建立数据库连接(或者如果可能的话,可以更新web2py或mysql驱动程序)
**更新2 **
我更好地检查了web2py dal.py
文件本身的代码 - 它默认尝试将连接设置为utf-8 - 但看起来它会尝试MySQLdb和pymysql驱动程序 - 如果你已经安装了两个尝试卸载pymysql ,只留下MySQLdb。