Невозможно десериализовать PyMongo ObjectId из JSON - PullRequest
10 голосов
/ 07 декабря 2011

Я, похоже, не могу десериализовать мой документ MongoDB JSON с BSON json_util .

Функция json.loads душит строку ObjectId().Я понял, что json_util способен обрабатывать формат ObjectId MongoDB и преобразовывать его в пригодный для использования 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 ]

18 голосов
/ 07 декабря 2011

Я думаю, что ваша строковая форма на самом деле выглядит как представление 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, похоже, не имеет какого-либо типа обработки для присутствия ObjectId () вфактическое представление строки json.

3 голосов
/ 07 декабря 2011

Здесь есть две проблемы:

  1. Строка, которую вы пытаетесь JSON-декодировать, не является JSON, это строковое представление словаря Python. В частности, проблема в том, что u'_id' не является допустимым ключом JSON (ключи JSON являются строками в кавычках; здесь «u» обозначает строку Unicode Python, которая в JSON не имеет смысла)

  2. json_util.object_hook не делает ObjectId доступным для JSON; модуль json декодирует JSON, а затем вызывает обратный вызов object_hook с каждым декодированным объектом. json_util.object_hook будет искать определенные шаблоны, определенные в строгом режиме MongoDB Extended JSON .

См. Ответ @ jdi для примеров того, как правильно использовать json_util.

...