2010-05-05 35 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

相關問題