I'm trying to use MySQL Connector/Python from mysql.com with Python 3.
我有UTF-8编码的表,当我取行时,所有的字符列都返回bytearray
,这会造成一些混乱。
如何直接获取str
?
UPD:
# -*- coding: utf-8 -*-
import mysql.connector
con = mysql.connector.connect( user ="root", db = "vg_site_db", charset = 'utf8' )
cursor = con.cursor()
sql = """select caption from domains
"""
cursor.execute( sql )
row = cursor.fetchone()
while row is not None:
print( row )
row = cursor.fetchone()
输出:
(bytearray(b'ezsp.ru'),)
(bytearray(b'eazyshop.ru'),)
(bytearray(b'127.0.0.1:8080'),)
(bytearray(b'rmsvet.ru'),)
我想要:
('ezsp.ru',)
('eazyshop.ru',)
('127.0.0.1:8080',)
('rmsvet.ru',)
更新2:
我的表使用COLLATE utf8_bin
。
6条答案
按热度按时间lskq00tm1#
看起来当你使用二进制排序时会发生这种情况,至少我也是这样。要将字节数组转换成Unicode字符串,你可以添加一个自定义转换器类:
z9ju0rcb2#
当各个列使用 binary collation(例如
utf8_bin
)定义时,MySQL连接器将字符串(使用CHAR
、VARCHAR
和TEXT
数据类型存储)返回为bytearray
。您必须对值调用.decode()
以获取Python字符串,例如:也就是说,除非您有使用
utf8_bin
的特定要求,否则在数据库级别使用带有排序规则utf8mb4_unicode_ci
的utf8mb4
字符集是一个更好的主意。这将解决您的问题并允许完全的Unicode支持。有关详细信息,请参阅this和this。hec6srdp3#
将
mysql-connector-python==8.0.17
添加到requirements.txt为我解决了这个问题。wqsoz72f4#
虽然投票最多的答案(@danmichaelo)当然有效,但我想提供我的版本,解决一个主要的“但是”,这已经由@Tominator指出;自定义转换器类现在必须继承
MySQLConverterBase
而不是MySQLConverter
。您不希望继承MySQLConverter
(即使如@danmichaelo所指出的,它继承了MySQLConverterBase
)的原因是,它将在每个返回值上调用MySQLConverter
类中的相应转换器。这将实现您可能不需要的逻辑。为了避免上述情况,您有两种选择:第一,您可以创建一个更高级的函数,该函数将获取数据并在检索到行后更改这些行。
如果你仍然想使用定制的converter类方法,那么你应该按照文档中的建议继承
MySQLConverterBase
(https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html在mysql-connector-python==8.0.26之前有效,见下文),然后你可以扩展MySQLConverterBase.to_python
方法。P.S.类MyConverter可用于实现自定义转换器,方法是创建名称与
MySQLConverter
类相同的函数(在此处查找该类:例如,我希望将TINYINT转换为bool,并添加了名为MyConverter._TINY_to_python(self, value, desc=None)
的方法--更新mysql连接器-python==8.0.27--
在8.0.27版本中,如果你创建一个继承了MySQLConverterBase的转换器类,你可能会得到一个错误消息 “期望一个类似字节的对象,发现了str”。我不清楚为什么会发生这种情况,但是我上面关于创建定制转换器的回答似乎不再成立了。相反,你现在应该继承
MySQLConverter
类:nnt7mjpx5#
我不认为你可以让游标返回字符串,MySQL Connector Documentation说他们选择返回字节数组,这样他们只需要为Python2和Python3维护一个代码库:
使用“原始”游标,返回的值是bytearray类型,这对于Python 2和Python 3返回相同的数据是必要的。
我使用列表解析来解码行中的每个字节数组,从而解决了这个问题:
iszxjhcz6#
解决这个问题的一个简单方法是确保您正在从MySQL表中检索"字符串"。为此,您只需在查询中添加CAST,如下所示:
这应该对你有用。