gpt4 book ai didi

python - mysql-python 整理问题 : how to force unicode datatype?

转载 作者:行者123 更新时间:2023-11-29 02:04:07 25 4
gpt4 key购买 nike

出于某些目的,我不得不将数据库中的字段排序规则从 utf8_unicode_ci 更改为 utf8_bin。事实证明,这种变化导致了 python 数据类型的变化。

问题是如何强制 mysql-python 将 unicode 对象返回给 python

这是一个显示问题的示例(显式字符集强制使用 use_unicode=1):

>>> con = MySQLdb.connect(..., charset='utf8')
>>> c = c.cursor()
>>> c.execute('SELECT %s COLLATE utf8_bin', u'м')
1L
>>> c.fetchone()
('\xd0\xbc',)
>>> c.description
(("'\xd0\xbc' COLLATE utf8_bin", 253, 2, 3, 3, 31, 0),)


>>> c.execute('SELECT %s COLLATE utf8_unicode_ci', u'м')
1L
>>> c.fetchone()
(u'\u043c',)
>>> c.description
(("'\xd0\xbc' COLLATE utf8_unicode_ci", 253, 2, 3, 3, 31, 0),)

在我的数据库中,字段是 VARCHAR 类型,但更改后它们的行为类似于 BINARY,这不是我想要的。

最佳答案

事实证明,这个问题比较尴尬。简而言之,MySQL string datatypes 中的大多数变种和物种使用附加的 BINARY 标志映射到 MySQL 接口(interface)中的单一数据类型。

因此,MySQL 的 VARCHARVARBINARY 和字符串文字映射到列类型中相同的 MySQLdb.constants.FIELD_TYPE.VAR_STRING 类型定义,但是当类型为 VARBINARY 或使用 *_bin 排序规则排序的字符串时,有一个额外的 MySQLdb.constants.FLAG.BINARY 标志。

尽管有一个 MySQLdb.constants.FIELD_TYPE.VARCHAR 类型,但我没找到它是什么时候使用的。正如我所说,MySQL VARCHAR 列映射到 FIELD_TYPE.VAR_STRING

如果您的应用程序使用真正的二进制字符串(例如,您存储图像并使用与文本相同的连接来获取它们),解决方案将变得相当脆弱,因为它假定将所有二进制字符串解码为 un​​icode。虽然,它有效。

作为官方docs状态:

Because MySQL returns all data as strings and expects you to convert it yourself. This would be a real pain in the ass, but in fact, _mysql can do this for you. (And MySQLdb does do this for you.) To have automatic type conversion done, you need to create a type converter dictionary, and pass this to connect() as the conv keyword parameter.

在实践中,真正痛苦的可能是构建您自己的转换器字典的过程。但是您可以从 MySQLdb.converters.conversions 导入默认值并对其进行修补,甚至可以在 Connection 的实例上对其进行修补。诀窍是为 FLAG.BINARY 标志删除一个特殊的转换器,并为所有情况添加一个解码器。如果您为 MySQLdb.connect 显式指定 charset 参数,它会强制使用 use_unicode=1 参数,这会为您添加解码器,但您可以自己做:

>>> con = MySQLdb.connect(**params)
>>> con.converter[FIELD_TYPE.VAR_STRING]
[(128, <type 'str'>), (None, <function string_decoder at 0x01FFA130>)]
>>> con.converter[FIELD_TYPE.VAR_STRING] = [(None, con.string_decoder)]
>>> c = con.cursor()
>>> c.execute("SELECT %s COLLATE utf8_bin", u'м')
1L
>>> c.fetchone()
(u'\u043c',)

如果需要,您可能需要对 FIELD_TYPE.STRING 进行相同的修改。

另一种解决方案是将显式 use_unicode=0 传递给 MySQLdb.connect 并在您的代码中进行所有解码,但我不会这样做。

希望,这可能对某人有用。

关于python - mysql-python 整理问题 : how to force unicode datatype?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9522413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com