【问题标题】:How do you store accented characters coming from a web service into a database?如何将来自 Web 服务的重音字符存储到数据库中?
【发布时间】:2010-05-06 06:26:19
【问题描述】:

我通过网络服务获取了以下单词:André

在 Python 中,该值类似于:“Andr\u00c3\u00a9”。然后使用json.loads对输入进行解码:

>>> import json
>>> json.loads('{"name":"Andr\\u00c3\\u00a9"}')
>>> {u'name': u'Andr\xc3\xa9'}

当我将上述内容存储在 utf8 MySQL 数据库中时,使用 Django 存储数据如下:

SomeObject.objects.create(name=u'Andr\xc3\xa9')

从 mysql shell 查询 name 列或在网页中显示它会给出: André

网页以utf8显示:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

我的数据库是用utf8配置的:

mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci | 
| collation_database   | utf8_unicode_ci | 
| collation_server     | utf8_unicode_ci | 
+----------------------+-----------------+
3 rows in set (0.00 sec)

mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       | 
| character_set_connection | utf8                       | 
| character_set_database   | utf8                       | 
| character_set_filesystem | binary                     | 
| character_set_results    | utf8                       | 
| character_set_server     | utf8                       | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

如何从 Web 服务中检索单词 André,将其正确存储在数据库中而不会丢失数据,并以原始形式将其显示在网页上?

【问题讨论】:

  • 到目前为止,我认为这里没有问题。您从 Python 中看到的是字符串“André”的 Unicode 表示。每个字符存储在两个字节中。当您将其存储在 MySQL 中时,数据库引擎会即时自动将其转换为 UTF-8 编码。在 UTF-8 中,有些字符仅使用 1 个字节存储,而有些字符使用多个字节存储,但这里没有数据丢失,可以从 UTF-8 编码表示中随时获取原始字符串。
  • 虽然与您的技术堆栈不是 100% 相同,但请查看 stackoverflow.com/questions/279170/utf-8-all-the-way-through,了解如何通过所有层无损处理 utf-8。
  • @Tamas:错误;看u'Andr\xc3\xa9'; e-acute 占用 4 个字节;见@Bernd 的回答

标签: python mysql django


【解决方案1】:

错误已经在您传递给 json.loads() 的字符串中。 \u00c3 是“波浪号”,\00a9 是版权标志。 é 正确的是 \u00e9。

可能该字符串已由发送方以 UTF-8 编码,并由接收方解码为 ISO-8859-1。

例如,如果您运行以下 Python 脚本:

# -*- encoding: utf-8 -*-

import json

data = {'name': u'André'}
print('data: {0}'.format(repr(data)))

code = json.dumps(data)
print('code: {0}'.format(repr(code)))

conv = json.loads(code)
print('conv: {0}'.format(repr(conv)))

name = conv['name']
print(u'Name is {0}'.format(name))

输出应如下所示:

data: {'name': u'Andr\xe9'}
code: '{"name": "Andr\\u00e9"}'
conv: {u'name': u'Andr\xe9'}
Name is André

在 Python 2.x 中管理 unicode 有时会令人讨厌。不幸的是,Django 还不支持 Python 3。

【讨论】:

  • +1 但我不明白 Python 3.x 如何阻止人们使用 rawbytes.decode('latin1') 而不是 rawbytes.decode('utf8')。数据不以 Unicode 存储和传输;它仍然被编码成字节,并且接收者仍然需要知道哪个编码来解码它。
  • 用什么来检查\u00c3、\00a9或\u00e9的实际值?
  • @John Machin:你是对的。然而,在大多数情况下,接收器应该能够导出编码。例如,如果 Web 服务器以特定编码发送带有表单的 html 页面,实际上所有浏览器都会以相同编码发送回表单数据。 @Thierry Lam:如果您在系统上的某些附件菜单下找不到字符映射查看器,请尝试 google 搜索“unicode codepoints”。示例网站:inamidst.com/stuff/unidata
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 2011-01-04
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 2013-10-14
相关资源
最近更新 更多