2013-05-15 14 views
2

我有一個系統,從各種來源讀取數據並將它們存儲在MongoDB中。我收到的數據已經在utf-8或unicode中正確編碼。文件鬆散地相關,並且在模式中有很大不同,如果您願意的話。我如何找到哪個值導致bson.errors.InvalidStringData

每隔一段時間,文檔的字段值都是純二進制數據,如JPEG圖像。我知道如何將該值包裝在bson.binary.Binary對象中以避免bson.errors.InvalidStringData異常。

有沒有辦法告訴文件的哪個部分使pymongo驅動程序提出bson.errors.InvalidStringData,還是我必須嘗試轉換每個字段才能找到它?

(+如果碰巧二進制對象恰好是一個有效的Unicode字符串或UTF-8,它會被存儲爲一個字符串,這是很正常)

+0

請問請注意pymongo什麼時候在你的情況下拋出'InvalidStringData'?我問,因爲你說過數據是用UTF-8編碼的,但是,正如文檔所述,在讀取非UTF8數據時([docs](http://api.mongodb.org/)蟒蛇/ 1.7/API/pymongo/errors.html#pymongo.errors.InvalidStringData))。謝謝。 – alecxe

+0

當文檔的字段值爲純二進制數據時,如JPEG圖像或X509證書。我從來沒有得到這個字符串的錯誤。 – ixe013

回答

3

PyMongo具有兩個BSON實現方式中,一個在Python可移植性和一個在下速度。 Python版本中的_make_c_string會告訴你它編碼失敗,但C版本顯然不是你正在使用的。你可以通過import bson; bson.has_c()知道你有哪些BSON實現。我已經提交PYTHON-533,它很快就會被修復。

+0

的確,'bson.has_c()'返回'True'。我會接受你的回答而不是我的回答。 – ixe013

0

(回答我的問題)

你無法從異常中得知,並且需要重新編寫驅動程序才能支持該功能。代碼bson/__init__.py。有一個函數名爲_make_c_string,如果字符串將在UTF-8中編碼時引發UnicodeError,則會引發InvalidStringData。同樣的功能是用於兩個鍵的和值爲字符串的值

換句話說,在代碼的這一點上,驅動程序不知道它是在處理一個鍵還是一個值。

有問題的數據作爲原始字符串到異常的構造過去了,但對於原因,我不明白,它不來的司機出來。

>>> bad['zzz'] = '0\x82\x05\x17' 
>>> try: 
...  db.test.insert(bad) 
... except bson.errors.InvalidStringData as isd: 
...  print isd 
... 
strings in documents must be valid UTF-8 

但是,這並不重要:你必須查找該值的鍵反正。

最好的方法是迭代這些值,嘗試在utf-8中對它們進行解碼。如果引發UnicodeDecodeError,則將該值包裝在二進制對象中。

有點像這樣:

try: 
    #This code could deal with other encodings, like latin_1 
    #but that's not the point here 
    value.decode('utf-8') 
except UnicodeDecodeError: 
    value = bson.binary.Binary(str(value)) 
相關問題