【问题标题】:How can I find which value caused a bson.errors.InvalidStringData如何找到导致 bson.errors.InvalidStringData 的值
【发布时间】:2013-05-10 11:16:06
【问题描述】:

我有一个系统可以从各种来源读取数据并将它们存储在 MongoDB 中。我收到的数据已经用 utf-8 或 unicode 正确编码。文档是松散相关的,并且在 schema 中变化很大,如果您愿意的话。

文档有时会有一个纯二进制数据的字段值,例如 JPEG 图像。我知道如何将该值包装在 bson.binary.Binary 对象中以避免 bson.errors.InvalidStringData 异常。

有没有办法判断文档的哪个部分使 pymongo 驱动程序引发bson.errors.InvalidStringData,或者我必须尝试转换每个字段才能找到它?

(+如果一个二进制对象碰巧是一个有效的 unicode 字符串或 utf-8,它将被存储为一个字符串,这没关系)

【问题讨论】:

  • 您能否请注意 pymongo 在您的情况下何时抛出 InvalidStringData?我之所以问,是因为您说过数据是用 UTF-8 编码的,但是,正如文档所述,在读取非 UTF8 数据时会引发此错误 (docs)。谢谢。
  • 当文档具有纯二进制数据的字段值时,例如 JPEG 图像或 X509 证书。我从来没有在字符串上遇到这个错误。

标签: mongodb exception pymongo bson


【解决方案1】:

PyMongo 有两个 BSON 实现,一个用 Python 实现可移植性,一个用 C 实现速度。 Python 版本中的_make_c_string 会告诉您它未能编码的内容,但显然您正在使用的 C 版本不会。您可以使用import bson; bson.has_c() 判断您拥有哪个 BSON 实现。我已经提交了PYTHON-533,很快就会修复。

【讨论】:

  • 确实,bson.has_c() 返回True。我会接受你的回答而不是我的回答。
【解决方案2】:

(回答我自己的问题)

您无法从异常中分辨出来,并且需要对驱动程序进行一些重写才能支持该功能。

代码在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,则将值包装在 Binary 对象中。

有点像这样:

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))

【讨论】:

    猜你喜欢
    • 2012-06-23
    • 2020-08-22
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多