如何在Python中读取包含ObjectId和ISODate的json文件?

时间:2018-10-05 20:01:24

标签: python json python-3.x pymongo

我想读取一个包含ObjectId和ISODate的JSON文件。

JSON数据:

PATH = '/custom-static-files/

2 个答案:

答案 0 :(得分:3)

我想在Maviles'answer的基础上增加一些其他一些SO问题的注释。

首先,从《 {Unable to deserialize PyMongo ObjectId from JSON》中我们了解到,这些数据看起来像是实际BSON / MOngo扩展JSON对象的Python表示形式。本地BSON文件也是二进制文件,而不是文本文件。

第二,从«How can I use Python to transform MongoDB's bsondump into JSON?»开始,我们可以扩展Fabian Fagerholm的答案:

def read_mongoextjson_file(filename):
    with open(filename, "r") 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'ISODate\s*\(\s*(\S+)\s*\)',
                          r'{"$date": \1}',
                          jsondata)
        jsondata = re.sub(r'NumberInt\s*\(\s*(\S+)\s*\)',
                          r'{"$numberInt": "\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)

        return data

如您所见,比较以前的版本和这个版本,处理类型非常简单。将MongoDB Extended JSON reference用于您需要的其他任何内容。

另外两个警告:

  • 我正在处理的文件是一系列对象,但这不是列表,我通过将所有内容放在方括号中来解决:
   bsondata = '['+f.read()+']'

否则,我将在第一个对象的末尾得到一个JSONDecodeError: Extra data: line 38 column 2 (char 1016)

pip uninstall bson
pip uninstall pymongo
pip install pymongo

这是一个paste,上面有完整的示例。

答案 1 :(得分:0)

我遇到了同样的问题,并且bson包仅在您已经具有dict类型的数据时才有用。

如果您已将它保存在字典中,则可以将其转换为这样的json(link):

from bson import json_util
import json

resulting_json = json.dumps(your_dict, default=json_util.default)

如果将其作为字符串,bson将无济于事。所以我只是删除了对象,并制作了一个严格的json字符串,然后将其转换为dict:

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

具有以下内容的文件:

{ "_id" : ObjectId("5baca841d25ce14b7d3d017c"), "country" : "in", "state" : "", "date" : ISODate("1902-01-31T00:00:00.000Z")}

将输出此字典:

     {  "_id" : "5baca841d25ce14b7d3d017c",
        "country" : "in",
        "state" : "",
        "date" : "1902-01-31T00:00:00.000Z"}
相关问题