无法从JSON反序列化PyMongo ObjectId

10 投票
2 回答
13488 浏览
提问于 2025-04-17 07:51

我似乎无法用BSON的 json_util 来反序列化我的MongoDB JSON文档。

json.loads函数在处理 ObjectId() 字符串时出现了问题。我原本以为json_util可以处理MongoDB的ObjectId格式,并将其转换为可用的JSON。

这是我的Python代码:

import json    
from bson import json_util

s = "{u'_id': ObjectId('4ed559abf047050c58000000')}"
u = json.loads(s, object_hook=json_util.object_hook)

我遇到了解码器异常:

...
    u = json.loads(s, object_hook=json_util.object_hook)
  File "\python27\lib\json\__init__.py", line 339, in loads
    return cls(encoding=encoding, **kw).decode(s)
  File "\python27\lib\json\decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "\python27\lib\json\decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 1 (char 1)

我是不是漏掉了什么?

2 个回答

4

这里有两个问题:

  1. 你尝试解码的字符串其实不是JSON格式,而是Python字典的字符串表示。具体来说,问题在于 u'_id' 不是一个有效的JSON键(JSON的键必须是用引号括起来的字符串;这里的“u”表示这是一个Python的unicode字符串,但在JSON中是没有意义的)。

  2. json_util.object_hook 并不能让 ObjectId 在JSON中可用;json模块会先解码JSON,然后对每个解码后的对象调用 object_hook 回调函数。json_util.object_hook 会根据MongoDB扩展JSON的严格模式来查找特定的模式。

可以参考 @jdi 的回答,看看如何正确使用 json_util

20

我觉得你的字符串形式实际上看起来像是Python的表示方式...

s = '{"_id": {"$oid": "4edebd262ae5e93b41000000"}}'
u = json.loads(s, object_hook=json_util.object_hook)

print u  # Result:  {u'_id': ObjectId('4edebd262ae5e93b41000000')}

s = json.dumps(u, default=json_util.default)

print s  # Result:  {"_id": {"$oid": "4edebd262ae5e93b41000000"}}

bson.json_util.object_hook这个函数似乎并没有处理实际的json字符串中包含ObjectId()的情况。

撰写回答