使用 Python 将 UTF-8 字符串写入 MySQL

2025-04-10 09:47:00
admin
原创
19
摘要:问题描述:我正在尝试将用户帐户数据从 Active Directory 推送到我们的 MySQL 服务器。此过程完美无缺,但不知何故,字符串最终显示了变音符号和其他特殊字符的编码版本。Active Directory 使用以下示例格式返回字符串:Mxc3xbcller这实际上是的 UTF-8 编码Müller...

问题描述:

我正在尝试将用户帐户数据从 Active Directory 推送到我们的 MySQL 服务器。此过程完美无缺,但不知何故,字符串最终显示了变音符号和其他特殊字符的编码版本。

Active Directory 使用以下示例格式返回字符串:Mxc3xbcller

这实际上是的 UTF-8 编码Müller,但我想将其写入Müller我的数据库而不是Mxc3xbcller

我尝试使用此行转换字符串,但它在数据库中产生相同的字符串:
tempEntry[1] = tempEntry[1].decode("utf-8")

如果我print "Mxc3xbcller".decode("utf-8")在 python 控制台中运行,输出是正确的。

有什么方法可以正确插入此字符串?对于想要这种精确格式的 Web 开发人员,我需要这种特定格式,我不知道为什么他不能直接使用 PHP 转换字符串。

附加信息:我正在使用 MySQLdb;表和列编码是 utf8_general_ci


解决方案 1:

正如@marr75 所建议的,请确保charset='utf8'在连接上进行设置。设置use_unicode=True并不是绝对必要的,因为它是通过设置字符集来暗示的。

然后确保将unicode对象传递给数据库连接,因为它将使用传递给游标的字符集对其进行编码。如果您传递的是 utf8 编码的字符串,则它在到达数据库时将被双重编码。

因此,类似于:

conn = MySQLdb.connect(host="localhost", user='root', password='', db='', charset='utf8')
data_from_ldap = 'Mxc3xbcller'
name = data_from_ldap.decode('utf8')
cursor = conn.cursor()
cursor.execute(u"INSERT INTO mytable SET name = %s", (name,))

您也可以尝试通过传递 init_command 参数强制连接使用 utf8,但我不确定这是否是必需的。5 分钟的测试应该可以帮助您做出决定。

conn = MySQLdb.connect(charset='utf8', init_command='SET NAMES UTF8')

另外,由于 4.1 版本太旧,所以不值得一提,请确保你正在使用 MySQL >= 4.1

解决方案 2:

假设您正在使用 MySQLdb,则需要在创建连接时传递 use_unicode=True 和 charset="utf8"。

更新:如果我对测试表运行以下命令,我会得到 -

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
>>> c = db.cursor()
>>> c.execute("INSERT INTO last_names VALUES(%s)", (u'Mxfcller', ))
1L
>>> c.execute("SELECT * FROM last_names")
1L
>>> print c.fetchall()
(('Mxc3xbcller',),)

这是“正确的方式”,字符被正确地存储和检索,你编写 php 脚本的朋友只是在输出时没有正确处理编码。

正如 Rob 指出的那样,use_unicode 和 charset 结合起来对于连接来说过于冗长,但是我对标准库之外最有用的 Python 库也有一种天生的偏执,因此我尝试明确说明,以便在库发生变化时能够轻松找到错误。

解决方案 3:

import MySQLdb

# connect to the database
db = MySQLdb.connect("****", "****", "****", "****") #don't use charset here

# setup a cursor object using cursor() method
cursor = db.cursor()

cursor.execute("SET NAMES utf8mb4;") #or utf8 or any other charset you want to handle

cursor.execute("SET CHARACTER SET utf8mb4;") #same as above

cursor.execute("SET character_set_connection=utf8mb4;") #same as above

# run a SQL question
cursor.execute("****")

#and make sure the MySQL settings are correct, data too

解决方案 4:

我找到了解决问题的方法。用 解码字符串.decode('unicode_escape').encode('iso8859-1').decode('utf8')终于成功了。现在一切都按预期插入了。完整的其他解决方案可以在这里找到:通过 python-ldap 使用 Active Directory 中的 unicode 编码字符串

解决方案 5:

最近我也遇到了同样的问题,字段值是字节字符串而不是unicode。下面是一些分析。

概述

通常,要从游标获取 unicode 值,只需将charset参数传递给连接构造函数并具有非二进制表字段(例如utf8_general_ci)。传递是无用的,因为只要有值,use_unicode它就会设置为 true 。charset

MySQLdb 尊重游标描述字段类型,因此如果游标中有DATETIME列,则值将转换为 Pythondatatime.datetime实例,DECIMAL等等decimal.Decimal,但二进制值将按原样表示为字节字符串。大多数解码器都在中定义MySQLdb.converters,可以通过向连接构造函数提供参数来在实例基础上覆盖它们conv

但 unicode 解码器在这里是个例外,这可能是一个设计缺陷。它们直接附加到其构造函数中的连接实例转换器。因此只能在 instance-basic 上覆盖它们。

解决方法

我们来看看问题代码。

import MySQLdb

connection = MySQLdb.connect(user = 'guest', db = 'test', charset = 'utf8')
cursor     = connection.cursor()

cursor.execute(u"SELECT 'abcdё' `s`, ExtractValue('<a>abcdё</a>', '/a') `b`")

print cursor.fetchone() 
# (u'abcd/u0451', 'abcdxd1x91')
print cursor.description 
# (('s', 253, 6, 15, 15, 31, 0), ('b', 251, 6, 50331648, 50331648, 31, 1))
print cursor.description_flags 
# (1, 0)

它显示b字段以字节字符串而不是 unicode 形式返回。但是它不是二进制的MySQLdb.constants.FLAG.BINARY & cursor.description_flags[1](MySQLdb 字段标志)。这似乎是库中的错误(已打开#90)。但我认为其原因是MySQLdb.constants.FIELD_TYPE.LONG_BLOB(MySQLdb 字段类型cursor.description[1][1] == 251)根本没有转换器。

import MySQLdb
import MySQLdb.converters as conv
import MySQLdb.constants as const

connection = MySQLdb.connect(user = 'guest', db = 'test', charset = 'utf8')
connection.converter[const.FIELD_TYPE.LONG_BLOB] = connection.converter[const.FIELD_TYPE.BLOB]
cursor = connection.cursor()

cursor.execute(u"SELECT 'abcdё' `s`, ExtractValue('<a>abcdё</a>', '/a') `b`")

print cursor.fetchone()
# (u'abcd/u0451', u'abcd/u0451')
print cursor.description
# (('s', 253, 6, 15, 15, 31, 0), ('b', 251, 6, 50331648, 50331648, 31, 1))
print cursor.description_flags
# (1, 0)

因此,通过操作连接实例converter字典,可以实现所需的unicode解码行为。

如果您想覆盖该行为,这里是构造函数之后可能的文本字段的字典条目的样子。

import MySQLdb
import MySQLdb.constants as const

connection = MySQLdb.connect(user = 'guest', db = 'test', charset = 'utf8')
print connection.converter[const.FIELD_TYPE.BLOB]
# [(128, <type 'str'>), (None, <function string_decoder at 0x7fa472dda488>)]

MySQLdb.constants.FLAG.BINARY == 128。这意味着如果字段具有二进制标志,则它将为str,否则将应用 unicode 解码器。因此,如果您也想尝试转换二进制值,则可以弹出第一个元组。

解决方案 6:

(想回复以上答案但声誉不够......)

在这种情况下无法获得unicode结果的原因是:

>>> print c.fetchall()
(('Mxc3xbcller',),)

是MySQLdb 1.2.x 中带有 *_bin 排序规则的一个错误,请参阅:

http://sourceforge.net/tracker/index.php?func=detail&aid=1693363&group_id=22307&atid=374932
http://sourceforge.net/tracker/index.php?func=detail&aid=2663436&group_id=22307&atid=374932

在这种特殊情况下(排序规则utf8_bin-或[任何] _bin...),您必须预期“原始”值,这里是 utf-8(是的,这很糟糕,因为没有通用的修复方法)。

解决方案 7:

还有一种情况可能比较罕见。

如果您首先在 mysqlworkbench 中创建一个模式,您将收到编码错误,并且无法通过添加字符集配置来解决它。

这是因为mysqlworkbench默认使用latin1创建模式,所以你应该首先设置字符集!
在此处输入图片描述

解决方案 8:

和 db.set_character_set('utf8'),暗示 use_unicode=True ?

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用