在Python中读取BSON文件?

在Python中读取BSON文件?,python,mongodb,bson,Python,Mongodb,Bson,我想在Python中读取BSON格式的Mongo转储并处理数据。我使用的是Python(我更喜欢使用Python而不是pymongo依赖),但它没有解释如何从文件中读取 这就是我正在尝试的: bson_file = open('statistics.bson', 'rb') b = bson.loads(bson_file) print b[0] 但我得到: Traceback (most recent call last): File "test.py", line 11, in <

我想在Python中读取BSON格式的Mongo转储并处理数据。我使用的是Python(我更喜欢使用Python而不是pymongo依赖),但它没有解释如何从文件中读取

这就是我正在尝试的:

bson_file = open('statistics.bson', 'rb')
b = bson.loads(bson_file)
print b[0]
但我得到:

Traceback (most recent call last):
  File "test.py", line 11, in <module>
    b = bson.loads(bson_file)
  File "/Library/Python/2.7/site-packages/bson/__init__.py", line 75, in loads
    return decode_document(data, 0)[1]
  File "/Library/Python/2.7/site-packages/bson/codec.py", line 235, in decode_document
    length = struct.unpack("<i", data[base:base + 4])[0]
TypeError: 'file' object has no attribute '__getitem__'
回溯(最近一次呼叫最后一次):
文件“test.py”,第11行,在
b=bson.load(bson\u文件)
文件“/Library/Python/2.7/site-packages/bson/_-init___uuu.py”,第75行,在loads中
返回解码文档(数据,0)[1]
decode_文档中的文件“/Library/Python/2.7/site packages/bson/codec.py”,第235行

length=struct.unpack(“
loads
需要一个字符串(这是“s”代表的),而不是一个文件。请尝试从文件中读取,并将结果传递给
loads

文档说明:

> help(bson.loads)
Given a BSON string, outputs a dict.
您需要传递一个字符串。例如:

> b = bson.loads(bson_file.read())

我发现这在mongodb 2.4 BSON文件和PyMongo的“BSON”模块中非常有效:

import bson
with open('survey.bson','rb') as f:
    data = bson.decode_all(f.read())
它返回了一个字典列表,这些字典与存储在mongo集合中的JSON文档相匹配

在BSON中,f.read()数据如下所示:

>>> rawdata[:100]
'\x04\x01\x00\x00\x12_id\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02_type\x00\x07\x00\x00\x00simple\x00\tchanged\x00\xd0\xbb\xb2\x9eI\x01\x00\x00\tcreated\x00\xd0L\xdcfI\x01\x00\x00\x02description\x00\x14\x00\x00\x00testing the bu'        

bson.loads似乎并不需要一个文件(如
loads
方法的文档中明确指出的)但是批准的答案是一种更好的方法,为了使用这个答案的代码,你需要使用
pip install pymongo
而不是
pip install bson
=
pip install pybson
。两者都有
import bson
语句。请看@Max Maxmeister到目前为止,另一个答案的示例对我来说没有帮助一个带有MungDB BSON转储文件的多行文件的正常情况,除非它没有被回答,否则另一个答案不仅仅是一个更好的方法。@劳伦兹我考虑<代码> BSON.Load 更好,因为这个函数是为这个精确的用例设计的。我的答案是处理原始数据,如果你是,我想它可能更灵活。加载未正确编码的内容。如果您需要单独加载文件中的每一行,您可以在每一行上尝试
bson.loads
?pybson的
bson.loads
似乎会在您有多行时使事情变得复杂。请参阅pybson答案上的注释。至少从我在实践中的经验来看ce.pymongo的
import-bson
的答案很好。我需要这一点来处理具有多行的bson文件的非常普通的示例,在这个示例中,我使用.readlines()而不是.read()。这会引发一个错误。最好的答案是,你是说文件中有多个bson对象,每行一个吗?会
b=[bson.loads(line)对于bson_文件中的行。readlines()]
在这种情况下工作?抛出错误:
[pybson.load(line)for line in open(filename,'rb').readlines()]回溯(最近一次调用):文件“”,文件“”中的第1行,文件“”中的第1行,文件“C:\Users\USER\AppData\Local\Programs\Python38-32\lib\site packages\pybson\\ init\uuuuuuuuuuuuuy.py,第47行,如果数据[end\u point-1]不在('\0',0)中,则加载返回解码文档(数据,0)[1]文件“C:\Users\USER\AppData\Local\Programs\Python38-32\lib\site packages\pybson\codec.py”,第277行,在解码文档中:Indexer Ror:index out range
我已安装并导入了它,它与pymongo
导入bson
不同,请参阅。只要没有安装pymongo(pymongo
导入bson
占主导地位),您的
导入bson
是相同的。readlines()无法正确拆分字符串,需要的是
将open(filename,'rb')作为f:b=f.read()listStrByte=re.split(rb'(?!\A)(?=\ \!)',b)print(len(listStrByte))listBs=[]用于listStrByte[:2]:listBs.append(pybson.loads(i))
有关此正则表达式拆分的详细信息,请参阅。我在[:2]停止了循环,在测试后去掉这个限制。我有限的pc在[:9]崩溃,因此我现在使用更简单的pymongo,请参阅pymongo的答案。