【问题标题】:JSON serializing MongodbJSON序列化MongoDB
【发布时间】:2013-11-09 13:23:14
【问题描述】:

我正在使用 python 包 pymongo 从 mongodb 数据库中检索数据。

>>> r = collection.find()   # returns an object of class 'Cursor'

然后我转换为列表

>>> l = list(r)             # returns a 'list' of 'dict'

这是 print(l) 返回的内容:

>>> [{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'_id': 1, u'name': u'name1', u'value': 11},{u'date': datetime.datetime(2013, 11, 10, 10, 45), u'_id': 2, u'name': u'name2', u'value': 22}]

现在我需要转换为 JSON 以便我可以操作它。

>>> json.dumps(l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2009, 11, 12, 11, 14) is not JSON serializable

我也尝试过关注http://api.mongodb.org/python/1.7/api/pymongo/json_util.html,但没有成功: 编辑:链接的最新版本是http://api.mongodb.org/python/current/api/bson/json_util.html

>>> json.dumps(l, default=json_util.default)  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
NameError: name 'json_util' is not defined  

注意:我需要使用 R 包 rPython 及其函数 rPython::python.get("l") 将这个结果推送到 R

附加问题:dict列表中每个字段前的u(u'Date'、u'name'等)是什么?

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    您指出的 pymongo 文档已过时。如果您使用的是 1.7 版,我建议您更新。使用更新的版本,您可以这样做:

    from bson.json_util import dumps
    
    dumps(l)
    

    https://pymongo.readthedocs.io/en/stable/api/bson/json_util.html

    侧面答案:u'name'、u'date'、u'_id' 等是数据库中文档的字段名称。

    【讨论】:

    • 谢谢!关于侧面问题,你是什么意思?我认为 'name','date','_id' 是字段名称
    • @rock u'literal' 是 Python 2 中的 Unicode 字符串。它们很像字符串,但在语法中使用前面的 u 指定。 Pymongo 正在将字段名称解码为 Unicode,这就是您以这种形式看到它们的原因。如果您的字段名称仅包含 ASCII 字符,则无需担心。
    • 好的,谢谢,会读到的。我可能不得不使用这种格式,因为我的字段也有日期
    • 谢谢我在瓶子框架上使用这个代码:@route('/admin/users', method=['OPTIONS', 'GET']) def get_users(): entity = db[' users'].find() l = list(entity) return dumps(l)
    • 转储方法需要大量时间处理 100 个文档
    【解决方案2】:
    from bson import json_util
    
    
    
    json.dumps(result,default=json_util.default)
    

    【讨论】:

    • 谢谢。与拉法的解决方案有什么区别?
    • 你的第二行返回我: Traceback(最近一次调用最后一次):文件“”,第 1 行,在 NameError: name 'json_util' is not defined
    • 你安装了 pymongo 吗?
    • 是的。我认为问题在于我有更新版本的 pymongo。现在我应该关注api.mongodb.org/python/current/api/bson/json_util.html
    • 你使用的是哪个版本的pymongo,因为不同版本的导入模块不同。对于旧版本,您也可以尝试 from pymongo import json_util。
    【解决方案3】:

    我遇到了同样的问题,我写了一个将文档转换为字典的代码。您可以将其用作参考。将 find_one() 得到的对象传递给 documentToJson() 方法,将 find() 的结果传递给 convertDocumentsToJson。 Json 名称中有类型,代码转换为 Dict 而不是 json。

    from bson.json_util import dumps
    
    class UtilService:
    
    def __init__(self):
        pass
    
    @staticmethod
    def pinCodeParser(path):
        location = {}
        f = open(path)
        for line in f:
            words = line.split()
            location[words[1]] = (words[-3],words[-2])
        return location
    
    @staticmethod
    def listHelper(str):
        s = []
        str = str.split(',')
        for e in str:
            s.append(e.replace("[","").replace("]",""))
        return s
    
    @staticmethod
    def parseList(str):
        if ',' in str:
            return UtilService.listHelper(str)
        return str
    
    @staticmethod
    def trimStr(str):
        return str.replace('"','')
    
    @staticmethod
    def documentToJson(document):
        document = eval(dumps(document))
        mp = {}
        for key, value in document.iteritems():
            if "_id" in key:
                mp["id"] = str(value["$oid"])
            else:
                mp[ UtilService.trimStr(key) ] = UtilService.parseList( value )
        return mp
    
    @staticmethod
    def convertDocumentsToJson(documents):
        result = []
        for document in documents:
            result.append(UtilService.documentToJson(document))
        return result
    

    【讨论】:

      【解决方案4】:

      这个帖子帮助了我 - 谢谢。

      想分享我的最终解决方案,以将 JSON 重新转换为 JSON/字典对象:(基于您的示例)

      from bson.json_util import dumps, loads
      r = collection.find()
      l = list(r) # Converts object to list
      d = dumps(l) # Converts to String
      dict_needed = loads(d[0]) # Serializes String and creates dictionary
      

      现在您在字典对象中拥有 JSON,并且可以根据需要进行编辑。

      【讨论】:

        【解决方案5】:

        在我的情况下,这个错误是由于烧瓶中的 mongo DB id 对象 你所要做的就是转换 id (注意:如果你需要 id 转换它,你也可以弹出它) 我正在分享我想出的解决方案,希望这对某人有所帮助

        from flask import jsonify
        
        def get_data(self,data):
             data['_id'] = str(data['_id'])
             return data
        
        app =  Flask(__name__)
        
        @app.route('/')
        def apimethod():
             temp = [self.get_data(i) for i in self.collection.find()]
             return jsonify(temp)
        

        pymongo 的转储也无济于事

        from bson.json_util import dumps,loads
        

        因为它返回的是字符串而不是 dict,这在我的情况下可以创建 API,如果我进行了转储,我必须再次加载。

        【讨论】:

        • 如果有人想要从 API 返回 JSON 而不是字符串,这是正确的答案。
        猜你喜欢
        • 2011-09-09
        • 1970-01-01
        • 1970-01-01
        • 2013-01-17
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多