pymongo 错误:bson.errors.InvalidBSON:'utf8' 编解码器无法解码位置 25 中的字节 0xa1:无效的起始字节

Posted

技术标签:

【中文标题】pymongo 错误:bson.errors.InvalidBSON:\'utf8\' 编解码器无法解码位置 25 中的字节 0xa1:无效的起始字节【英文标题】:pymongo error: bson.errors.InvalidBSON: 'utf8' codec can't decode byte 0xa1 in position 25: invalid start bytepymongo 错误:bson.errors.InvalidBSON:'utf8' 编解码器无法解码位置 25 中的字节 0xa1:无效的起始字节 【发布时间】:2016-07-18 19:22:45 【问题描述】:
tasks = list(self.collection.find().sort('_id',pymongo.DESCENDING).limit(1000))

我在使用 pymongo 解决程序时遇到了麻烦。

文件“D:\Python27\lib\site-packages\pymongo-3.2.1-py2.7-win-amd64.egg\pymongo\cursor.py”,第 1097 行,在下一个 文件“D:\Python27\lib\site-packages\pymongo-3.2.1-py2.7-win-amd64.egg\pymongo\cursor.py”,第 1039 行,在 _refresh 文件“D:\Python27\lib\site-packages\pymongo-3.2.1-py2.7-win-amd64.egg\pymongo\cursor.py”,第 903 行,在 __send_message _unpack_response 中的文件“D:\Python27\lib\site-packages\pymongo-3.2.1-py2.7-win-amd64.egg\pymongo\helpers.py”,第 133 行 bson.errors.InvalidBSON:“utf8”编解码器无法解码位置 25 中的字节 0xa1:无效起始字节

tasks =self.collection.find().sort('_id',pymongo.DESCENDING).limit(1000)
for task in tasks:  #If i use this way,it will also touch this problem

task = self.collection.find_one()#It would do so,too

我进入pymongo寻找原因。我发现问题可能是由以下代码引起的

    result = "cursor_id": struct.unpack("<q", response[4:12])[0],
          "starting_from": struct.unpack("<i", response[12:16])[0],
          "number_returned": struct.unpack("<i", response[16:20])[0],
          "data": bson.decode_all(response[20:], codec_options)

在 pymongo helper.py 133 行 在bson.decode_all中显示了关于'oid'的解码失败的问题,'oid'是mongo中的_id。然后我复制文档并使用新的_id制作相同的文档,然后我成功获取文档。

如何解决“for task in tasks:”样式的问题。

使用的pymongo版本:3.2.1

【问题讨论】:

【参考方案1】:

您需要将 unicode_decode_error_handler 参数传递给 MongoClient 并至少使用 pymongo 3.5.1。

import pymongo
import json
from pymongo import MongoClient

if __name__ == '__main__':

    client = MongoClient(
        host="whatever_your_host_is",
        maxPoolSize=50,
        unicode_decode_error_handler='ignore'
    )


    my_db=client['my_db']
    collection=my_db['my_collection']

    cursor = collection.find("whatever": "some_stuff")

    for document in cursor:
          print(document)

看起来在 Python 2.7 上默认设置了“忽略”,但在 Python 3.6.1 中你必须自己做。这将忽略 Unicode 错误并让光标继续迭代,pymongo 将尽力重建 JSON 数据。

【讨论】:

我看到'utf8' codec can't decode byte 0xfd in position 0: invalid start byte 并将unicode_decode_error_handler='ignore' 添加到构造函数中修复了它。【参考方案2】:

我最近收到了类似的错误消息,很难找到有关它的帮助。

快速解决

我解决了在 3.0 下降级 pymongo 版本的问题。 changelog of pymongo 在 3.0 版宣传“重写的纯 Python BSON 实现”。我发现新实现在以 BSON 格式序列化时无法管理 python utf8 和 unicode 编码。

分析

似乎错误来自您的数据库中的无效 bson ...类似于this。也许你应该发布你的错误there。

【讨论】:

我在bson.decode_file_iter(f) 遇到了这个问题。按照您的链接,我将其更改为bson.decode_file_iter(f, bson.CodecOptions(unicode_decode_error_handler="ignore")),这解决了我的问题。【参考方案3】:

我使用的是 Python 3.6,pymongo 3.4.0。

根据文档,您可以使用“with_options”方法克隆一个集合,这对我有用:

 col_article = col_article.with_options(codec_options = bson.CodecOptions(unicode_decode_error_handler="ignore"))

【讨论】:

以上是关于pymongo 错误:bson.errors.InvalidBSON:'utf8' 编解码器无法解码位置 25 中的字节 0xa1:无效的起始字节的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 PyMongo 查询中出现无效错误

Pymongo:使用 $setOnInsert 错误进行批量更新

集合对象不是 PyMongo 的可调用错误

pymongo 错误文档必须是 dict 的实例

Pymongo 更新不更新,并且没有错误

Pymongo GridFS 放置类型/属性错误