2010-03-26 20 views
3

我有一個簡單的dict對象我試圖通過pickle運行後存儲在數據庫中。看起來Django不喜歡試圖編碼這個錯誤。我已經檢查過MySQL,並且在拋出錯誤之前,查詢甚至沒有到達,所以我不認爲這是問題所在。該dict我存儲看起來像這樣:DjangoUnicodeDecodeError存儲pickle的數據時

{ 
    'ordered': [ 
     { 'value': u'First\xd1ame Last\xd1ame', 
      'label': u'Full Name' }, 
     { 'value': u'123-456-7890', 
      'label': u'Phone Number' }, 
     { 'value': u'[email protected]', 
      'label': u'Email Address' } ], 
    'cleaned_data': { 
     u'Phone Number': u'123-456-7890', 
     u'Full Name': u'First\xd1ame Last\xd1ame', 
     u'Email Address': u'[email protected]' }, 
    'post_data': <QueryDict: { 
     u'Phone Number': [u'1234567890'], 
     u'Full Name_1': [u'Last\xd1ame'], 
     u'Full Name_0': [u'First\xd1ame'], 
     u'Email Address': [u'[email protected]'] }>, 
    'user': <User: itis> 
} 

獲取引發的錯誤是:在52-53位置

「UTF-8」編解碼器不能解碼字節:無效數據。

位置52-53是醃製數據中\xd1(Ñ)的第一個實例。

到目前爲止,我已經圍繞StackOverflow挖掘並發現了一些問題,其中對象的數據庫編碼是錯誤的。這對我沒有幫助,因爲還沒有MySQL查詢。這發生在數據庫之前。在搜索數據上搜索unicode錯誤時,Google也沒有什麼幫助。

這可能是值得一提的,如果我不使用Ñ,這段代碼工作正常。

+0

這可能不是與酸洗本身有關,並且可能僅僅是一個unicode錯誤。這可能有助於http://www.amk.ca/python/howto/unicode – 2010-03-26 17:56:34

+0

什麼會導致你相信這可能是一個unicode錯誤?我對與國際角色合作很陌生,但一切似乎都是在我眼中編碼的。 – 2010-03-26 20:38:39

回答

3

非常感謝@prometheus,我找到了一個解決方案。基本上,您可以使用base64在將其插入數據庫之前對pickle.dumps()的輸出進行編碼。然後,您將轉向並使用base64解碼數據庫的輸出,然後將其傳遞到pickle.loads()

我的代碼現在看起來像這樣:

## Put the information into the database: 
self.raw_data = base64.b64encode(pickle.dumps(data)) 

## Get the information out of the database: 
return pickle.loads(base64.b64decode(self.raw_data)) 

再次感謝您@prometheus。

2

這是一個已知的問題,並有關於這個在Python bug-tracker討論:

我編寫Python數據結構到 數據庫時,今天就遇到了這個問題。在這種情況下只有ASCII是安全的。我瞭解到Python協議,即協議0僅爲ASCII。

現在我使用pickle + base64,但是,這使得調試更加困難。

無論如何,我認爲文檔應該清楚地說協議0不是 僅用於ASCII,因爲這在Python世界中很重要。例如, 我看到了這個問題,因爲Django使用我的輸入進行隱式unicode()轉換 ,該輸入失敗並顯示非ASCII。

+0

如果你想重寫我發佈的答案,我寧願給你找到答案的代表。 – 2010-03-29 17:18:58

+0

我很好,謝謝。這基本上就是我自己使用的代碼。 – nikola 2010-03-29 17:40:54

1

我認爲沒有必要這樣做。通常,應該可以將任何二進制數據存儲在數據庫中。

一個更糟的問題是酸洗不安全 - 如果數據庫可以從任何地方獲取數據,它可能會得到惡意的酸洗數據。