Kan PyMongo ObjectId niet van JSON deserialize

Ik kan mijn MongoDB JSON-document blijkbaar niet deserialiseren met de BSON json_util .

De json.loads-functie verstikt zich in de tekenreeks ObjectId() . Ik had json_util begrepen die het objectId-formaat van MongoDB kon verwerken en transformeren in bruikbare JSON.

Python-code:

import json    
from bson import json_util

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

Ik krijg de uitzondering van de decoder:

...
    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)

Mis ik iets?

8

2 antwoord

Ik denk dat je snaarvorm er in werkelijkheid uitziet als de pythonrepresentatie ...

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"}}

De functie bson.json_util.object_hook lijkt geen enkele vorm van afhandeling te hebben omdat er ObjectId() is in de eigenlijke json-tekenreeksrepresentatie.

16
toegevoegd
Ok, na het bekijken van de suggestie van @ dcrosta om MongoDB Extended JSON te herzien mongodb.org/display/DOCS/Mongo + Extended + JSON , laat me in plaats daarvan proberen de data_oid van TenGen BSON-type naar Strict JSON te converteren, dat wil zeggen "$ oid".
toegevoegd de auteur jdev, de bron
De suggestie van json.dumps werkte perfect. s = json.dumps (u, standaard = json_util.default), output {"_id": {"$ oid": "4ed559abf047050c58000000"}}. Bedankt @ jdi
toegevoegd de auteur jdev, de bron
@ SaradaAkurathi toen ik dit antwoord schreef. 5 jaar geleden was json_util onderdeel van de bson-module (zoals gedocumenteerd in het antwoord). Is dat niet langer het geval?
toegevoegd de auteur jdi, de bron
@ SaradaAkurathi Ik weet niet zeker wat uw probleem is. U kunt het beste worden bediend door een nieuwe vraag te openen met de details van uw probleem. Deze vraag is vrij oud en opmerkingen zijn niet echt de beste plek om problemen op te lossen
toegevoegd de auteur jdi, de bron
Hallo allemaal, ik wil ook ObjectId() van het mongo-resultaat converteren, ik heb geprobeerd bovenstaande code uit te voeren, ik ontvang de volgende fout NameError: algemene naam 'json_util' is niet gedefinieerd is elke bibliotheek i moet je importeren? , ik heb de bibliotheek bson geïmporteerd maar nog steeds dezelfde fout
toegevoegd de auteur Sarada Akurathi, de bron
@jdi, ik vond deze json_util voor json_util. optie bson.json_util.default is er nog steeds. probleem eerder met verkeerde import, nu importeerde ik de juiste bibliotheek, de bovenstaande fout is weg maar het resultaat is nog niet geconverteerd. Kun jij helpen wat er mis ging
toegevoegd de auteur Sarada Akurathi, de bron
ok bedankt, ik zal zeker een nieuwe vraag openen
toegevoegd de auteur Sarada Akurathi, de bron

Er zijn hier twee problemen:

  1. De tekenreeks die u probeert te JSON-decoderen is niet JSON, dit is de tekenreeksrepresentatie van een Python-woordenboek. In het bijzonder is het probleem dat u'_id ' geen geldige JSON-sleutel is (JSON-sleutels zijn aangehaalde tekenreeksen, de "u" hier geeft een Python-unicode-tekenreeks aan, die betekenisloos is in JSON)

  2. json_util.object_hook maakt ObjectId niet beschikbaar voor JSON; de module json decodeert de JSON en roept de call-call object_hook aan met elk gedecodeerd object. json_util.object_hook zoekt naar bepaalde patronen zoals gedefinieerd in de strikte modus van MongoDB Extended JSON .

Zie @ jdi's antwoord voor voorbeelden van hoe je json_util goed kunt gebruiken.

3
toegevoegd
RE: 1. Hallo dcrosta, de string die ik in mijn voorbeeld had gebruikt, is overgenomen uit het applog, vandaar de extra python unicode 'u'.
toegevoegd de auteur jdev, de bron