Python与MySql unicode问题
我需要从我的python脚本调用MySQL存储过程。作为参数之一,我传递了一个unicode字符串(俄语),但我得到一个错误;Python与MySql unicode问题
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-1: ordinal not in range(256)
我的脚本:
self.db=MySQLdb.connect("localhost", "usr", "pass", "dbName")
self.cursor=self.db.cursor()
args=("какой-то текст") #this is string in russian
self.cursor.callproc('pr_MyProc', args)
self.cursor.execute('SELECT @_pr_MyProc_2') #getting result from sp
result=self.cursor.fetchone()
self.db.commit()
我读过设置charset='utf8'
shuld解决此问题,但是当我使用的字符串:
self.db=MySQLdb.connect("localhost", "usr", "pass", "dbName", charset='utf8')
这给了我另一个错误;
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcd1' in position 20: surrogates not allowed
另外我试图设置参数use_unicode=True
,这是行不通的。
更多的事情来检查: http://mysql.rjweb.org/doc.php/charcoll#python
可能的项目:
- 启动代码文件,
# -*- coding: utf-8 -*-
- (在代码中的文字) - 字面应该是U '......'
你可以提取HEX? какой-то текст
应该是这个在utf8中:D0BA D0B0 D0BA D0BE D0B9 2D D182 D0BE D182 20 D0B5 D0BA D181 D182
据我所知“# - * - coding:utf-8 - * - ”设置文件的编码,而不是字符串。所以它没有帮助。 – Gleb
它在你的情况下受伤了吗? –
MySQLdb模块与python 3不兼容。这可能是你遇到问题的原因。我建议使用不同的连接器,如PyMySQL或mysqlclient。
相关:23376103。
我正在使用mysqlclinet – Gleb
这里有一些想法。也许不是一个回应。我一直在玩蟒蛇/ MySQL的/ UTF-8/Unicode的过去,这是事情我记得:
看着Saltstack mysql的模块的评论:
https://github.com/saltstack/salt/blob/develop/salt/modules/mysql.py#L314-L322
# MySQLdb states that this is required for charset usage
# but in fact it's more than it's internally activated
# when charset is used, activating use_unicode here would
# retrieve utf8 strings as unicode() objects in salt
# and we do not want that.
#_connarg('connection_use_unicode', 'use_unicode')
connargs['use_unicode'] = False
_connarg('connection_charset', 'charset')
我们请参阅以避免更改结果字符串use_unicode设置为False,而charset(可能是utf-8)被设置为参数。 use_unicode更像是一个'请求',以响应为unicode字符串。
您可以在测试中检查实际使用情况,这里是: https://github.com/saltstack/salt/blob/develop/tests/integration/modules/test_mysql.py#L311-L361,数据库名为'标准语'。
现在关于消息UnicodeEncodeError:'utf-8'编解码器无法编码字符'\ udcd1'**。您正在使用** unicode,但您告诉模块它是utf-8。它不是utf-8,直到你在utf-8中编码你的unicode字符串。
也许你应该尝试:
args=(u"какой-то текст".encode('utf-8'))
至少在python3这是必需的,因为你的 “какой-тотекст” 是不是UTF-8在默认情况下。
什么是数据库的字符集?
使用:
show variables like "characetr%";
或看到你的数据库的字符集
也许你可以重新载入你的sys
在utf-8
,并尝试将字符串解码成utf-8
如下:
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
...
stringUtf8 = u''.join(string_original).decode('utf-8')
我看到这里有两个问题。
你有unicode,但你尝试通过设置参数“charset”来定义它为utf-8。您应该先将Unicode编码为utf-8或其他编码系统。
如果它不起作用,请尝试使用init_command ='SET NAMES UTF8'参数。
所以它看起来像:
conn = MySQLdb.connect(charset='utf8', init_command='SET NAMES UTF8')
你也可以这样试试:
cursor = db.cursor()
cursor.execute("SET NAMES UTF8;")
我有一个类似的问题,最近,但在PostgreSQL。在尝试了大量来自SO/Internet的建议后,我意识到问题出在我的数据库上。我不得不放弃我的数据库并重新安装Postgres,因为出于某种原因,它不允许我更改数据库的默认排序规则。我很匆忙,所以找不到更好的解决方案,但会推荐相同的,因为我只是在部署环境中启动我的应用程序。 一切顺利。
我遇到了类似的问题,这是由于数据库中无效的utf-8数据造成的;似乎MySQL不关心这个,但是Python做,因为这是继UTF-8的规格,它说that:
- 代理对中无法使用UTF-8
- 不成对的代理人都没有允许在utf-8中
如果你想“让它工作”,你将不得不截获MySQL数据包并使用你自己的转换器来执行临时替换。
这里的“处理”含代理人无效数据的一种方法:
def borked_utf8_decode(data):
"""
Work around input with unpaired surrogates or surrogate pairs,
replacing by XML char refs: look for "&#\d+;" after.
"""
return data.decode("utf-8", "surrogatepass") \
.encode("utf-8", "xmlcharrefreplace") \
.decode("utf-8")
注意处理的正确方法是上下文相关,但也有一些共同的替代方案中,像this one。
而且这里有一个方法插入到pymysql
这个的(另一种方式是猴子补丁场处理,例如见https://github.com/PyMySQL/PyMySQL/issues/631):`ARGS =:
import pymysql.converters
# use this in your connection
pymysql_use_unicode = False
conversions = pymysql.converters.conversions
conversions[pymysql.converters.FIELD_TYPE.STRING] = borked_utf8_decode
conversions[pymysql.converters.FIELD_TYPE.VAR_STRING] = borked_utf8_decode
conversions[pymysql.converters.FIELD_TYPE.VARCHAR] = borked_utf8_decode
它的工作原理(u“какой-тотекст”)'? –
@DanielRoseman不,我也试过了。 – Gleb
是这个蟒蛇2或3? –