如何使用Python转换MongoDB';将bsondump转换为JSON?

如何使用Python转换MongoDB';将bsondump转换为JSON?,python,json,mongodb,bson,Python,Json,Mongodb,Bson,所以我从MongoDB转储中获得了大量的.bson。我在命令行上使用,将输出作为stdin传输到python。这成功地将BSON转换为“JSON”,但实际上它是一个字符串,似乎不是合法的JSON 例如,输入线如下所示: { "_id" : ObjectId( "4d9b642b832a4c4fb2000000" ), "acted_at" : Date( 1302014955933 ), "created_at" : Date( 1302014955933 ), "updated_a

所以我从MongoDB转储中获得了大量的.bson。我在命令行上使用,将输出作为stdin传输到python。这成功地将BSON转换为“JSON”,但实际上它是一个字符串,似乎不是合法的JSON

例如,输入线如下所示:

{ "_id" : ObjectId( "4d9b642b832a4c4fb2000000" ),
  "acted_at" : Date( 1302014955933 ),
  "created_at" : Date( 1302014955933 ),
  "updated_at" : Date( 1302014955933 ),
  "_platform_id" : 3,
  "guid" : 72106535190265857 }
>>> import bson
>>> bs = open('file.bson', 'rb').read()
>>> for valid_dict in bson.decode_all( bs ):
....
我相信是的

当我读到这样一行时,我会:

json_line = json.dumps(line)
我得到:

"{ \"_id\" : ObjectId( \"4d9b642b832a4c4fb2000000\" ),
\"acted_at\" : Date( 1302014955933 ),
\"created_at\" : Date( 1302014955933 ),
\"updated_at\" : Date( 1302014955933 ),
\"_platform_id\" : 3,
\"guid\" : 72106535190265857 }\n"
仍然是

我也试过了

json_line = json.dumps(line, default=json_util.default)
(请参阅pymongo json_util-垃圾邮件检测阻止第三个链接) 它的输出似乎与上面的转储相同。加载时出现错误:

json_line = json.loads(line, object_hook=json_util.object_hook)
ValueError: No JSON object could be decoded
那么,如何将TenGen JSON的字符串转换为可解析的JSON呢?
(最终目标是将选项卡分隔的数据流传输到另一个数据库)

您拥有的是TenGen模式下Mongo Extended JSON的转储(请参阅)。一些可能的方法:

  • 如果可以再次转储,请通过MongoDB REST API使用严格的输出模式。这将为您提供真正的JSON,而不是您现在拥有的

  • 使用
    bson
    from将您已有的bson读入Python数据结构,然后对这些数据结构执行您需要的任何处理(可能输出JSON)

  • 使用MongoDB Python绑定连接到数据库,将数据转换成Python,然后执行所需的任何处理。(如果需要,您可以设置本地MongoDB实例,并将转储的文件导入其中。)

  • 将Mongo扩展JSON从TenGen模式转换为Strict模式。您可以开发一个单独的过滤器来执行此操作(从stdin读取,用Strict结构替换TenGen结构,并在stdout上输出结果),也可以在处理输入时执行此操作

  • 下面是一个使用Python和正则表达式的示例:

    import json, re
    from bson import json_util
    
    with open("data.tengenjson", "rb") as f:
        # read the entire input; in a real application,
        # you would want to read a chunk at a time
        bsondata = f.read()
    
        # convert the TenGen JSON to Strict JSON
        # here, I just convert the ObjectId and Date structures,
        # but it's easy to extend to cover all structures listed at
        # http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON
        jsondata = re.sub(r'ObjectId\s*\(\s*\"(\S+)\"\s*\)',
                          r'{"$oid": "\1"}',
                          bsondata)
        jsondata = re.sub(r'Date\s*\(\s*(\S+)\s*\)',
                          r'{"$date": \1}',
                          jsondata)
    
        # now we can parse this as JSON, and use MongoDB's object_hook
        # function to get rich Python data structures inside a dictionary
        data = json.loads(jsondata, object_hook=json_util.object_hook)
    
        # just print the output for demonstration, along with the type
        print(data)
        print(type(data))
    
        # serialise to JSON and print
        print(json_util.dumps(data))
    

    根据您的目标,其中一个应该是合理的起点。

    您可以将bson文件的行转换为以下格式:

    { "_id" : ObjectId( "4d9b642b832a4c4fb2000000" ),
      "acted_at" : Date( 1302014955933 ),
      "created_at" : Date( 1302014955933 ),
      "updated_at" : Date( 1302014955933 ),
      "_platform_id" : 3,
      "guid" : 72106535190265857 }
    
    >>> import bson
    >>> bs = open('file.bson', 'rb').read()
    >>> for valid_dict in bson.decode_all( bs ):
    ....
    

    每个有效的dict元素都将是一个有效的python dict,您可以将其转换为json。

    将整个bson文档加载到python内存是非常昂贵的

    如果您想将其流式传输,而不是加载整个文件并执行全部加载,您可以尝试使用此库


    您可以去掉数据类型并使用正则表达式获得严格的json:

    import json
    import re
    
    #This will outputs a iterator that converts each file line into a dict.
    def readBsonFile(filename):
        with open(filename, "r") as data_in:
            for line in data_in:
                # convert the TenGen JSON to Strict JSON
                jsondata = re.sub(r'\:\s*\S+\s*\(\s*(\S+)\s*\)',
                                  r':\1',
                                  line)
    
                # parse as JSON
                line_out = json.loads(jsondata)
    
                yield line_out
    

    你看过bson的
    了吗?除了删除Mongo依赖项之外,它还能做什么?我不明白这怎么会是我的问题,但我会再看一看。可能是重复的我看到了那个,并试图利用帮助。但是如果您注意到,他得到的字符串在“\u id”前面有一个前面的“u”,并且一个响应程序表示一个python unicodestring@boardrider那是什么?链接指向这个问题。是的,我在问题中链接到了扩展的JSON页面。我尝试过BSON库,但它没有达到我的目标。bsondump是我唯一能去工作的东西,但它给了我一根弦。转储或重新加载数据是不可行的选项。@PeterNachbaur:我在回答中添加了一个选项,以说明如何将TenGen JSON格式转换为严格的JSON。这就是你想要的吗?谢谢你继续帮助:)现在加载工作正常了。最后,我假设您指的是json.dumps而不是json_util.dumps(后者似乎不存在),但这不起作用。然而,我不确定我现在是否需要它,因为我有一个口述。干杯@没问题,想想这个很有趣奇怪的是,我有一个bson.json_util.dumps函数。但它可能只存在于mongo python代码的开发分支中。不管怎样,你已经有了口述,所以你现在可以做任何你想做的事;)祝你好运好办法。regex:)for循环不起作用:(回溯(最后一次调用):文件“”,第1行,在文件“/usr/local/lib/python2.7/dist packages/bson/_uinit__uuuuuuu.py”中,第473行,在decode_all end=len(data)-1 TypeError:File类型的对象没有len()