2010-05-05 46 views
4

我通过网络服务获取以下单词:André如何将来自Web服务的重音字符存储到数据库中?

从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查询名称列壳或在网页中显示它给: 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服务,妥善保存它而不会丢失数据数据库,并在其原有的网页上显示它形成?

+2

到目前为止,我在这里看不到任何问题。您从Python中看到的是您的字符串“André”的Unicode表示形式。每个字符都以两个字节存储。当您将其存储在MySQL中时,数据库引擎会自动将其转换为UTF-8编码。在UTF-8中,一些字符仅使用1个字节存储,而其他字符则使用多个字节,但这里没有数据丢失,原始字符串可以随时从UTF-8编码表示中获得。 – 2010-05-05 18:28:33

+0

虽然不是100%与您的技术堆栈相同,但请查看http://stackoverflow.com/questions/279170/utf-8-all-the-way-through以获得无损处理utf-8的好解释所有的层次。 – ataylor 2010-05-05 19:05:18

+0

@Tamas:WRONG;看看'u'Andr \ xc3 \ xa9''; e-acute占用4个字节;请参阅@ Bernd的回答 – 2010-05-05 23:51:57

回答

6

错误已经存在于您传递给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.

+0

+1,但我不明白Python 3.x如何阻止人们执行rawbytes.decode('latin1')'而不是'rawbytes.decode('utf8')'。数据不是以Unicode格式存储和传输的;它仍然被编码为字节,并且接收机仍然需要知道哪个编码来解码它。 – 2010-05-05 23:59:15

+0

你用什么来检查\ u00c3,\ 00a9或\ u00e9的实际值? – 2010-05-06 14:17:05

+0

@John Machin:你说得对。但是,在大多数情况下,接收器应该能够导出编码。例如,如果一个web服务器发送一个带有特定编码形式的html页面,几乎所有的浏览器都会以相同的编码发回表单数据。 @Thierry Lam:如果您的系统上的某些accessoiries菜单下找不到字符图查看器,请尝试Google查找“unicode codepoints”。示例网站:http:// inamidst。COM /材料/ UniData的/ – 2010-05-06 18:51:45

相关问题