Zoeken…


Invoering

In veel toepassingen moeten records van MongoDB worden geserialiseerd in JSON-indeling. Als uw records velden met type datum, datetime, objectId, binary, code, enz. Hebben, zult u TypeError: not JSON serializable tegenkomen TypeError: not JSON serializable uitzonderingen bij het gebruik van json.dumps . Dit onderwerp laat zien hoe dit te overwinnen.

Json_util gebruiken

json_util biedt twee helper-methoden, dumps en loads , die de native json-methoden omwikkelen en expliciete BSON-conversie naar en van json bieden.

Eenvoudig gebruik

from bson.json_util import loads, dumps
record = db.movies.find_one()
json_str = dumps(record)
record2 = loads(json_str)

als record is:

{ 
    "_id" : ObjectId("5692a15524de1e0ce2dfcfa3"), 
    "title" : "Toy Story 4", 
    "released" : ISODate("2010-06-18T04:00:00Z") 
}

dan wordt json_str :

{
    "_id": {"$oid": "5692a15524de1e0ce2dfcfa3"},
    "title" : "Toy Story 4", 
    "released": {"$date": 1276833600000}
}

JSONOptions

Het is mogelijk om het gedrag van dumps via een JSONOptions object. Twee sets opties zijn al beschikbaar: DEFAULT_JSON_OPTIONS en STRICT_JSON_OPTIONS .

>>> bson.json_util.DEFAULT_JSON_OPTIONS
    JSONOptions(strict_number_long=False, datetime_representation=0,
     strict_uuid=False, document_class=dict, tz_aware=True, 
     uuid_representation=PYTHON_LEGACY, unicode_decode_error_handler='strict',
     tzinfo=<bson.tz_util.FixedOffset object at 0x7fc168a773d0>) 

Om verschillende opties te gebruiken, kunt u:

  1. wijzig het DEFAULT_JSON_OPTIONS object. In dit geval worden de opties gebruikt voor alle volgende oproepen naar dumps :

     from bson.json_util import DEFAULT_JSON_OPTIONS
     DEFAULT_JSON_OPTIONS.datetime_representation = 2
     dumps(record)
    
  2. specificeer een JSONOptions in een aanroep naar dumps met behulp van de parameter json_options :

     # using strict
     dumps(record, json_options=bson.json_util.STRICT_JSON_OPTIONS)
    
     # using a custom set of options
     from bson.json_util import JSONOptions
     options = JSONOptions() # options is a copy of DEFAULT_JSON_OPTIONS
     options.datetime_representation=2
     dumps(record, json_options=options)
    

De parameters van JSONOptions zijn:

  • strict_number_long : Indien true, worden Int64-objecten gecodeerd in het strikte modustype NumberLong van MongoDB Extended JSON, dwz {"$numberLong": "<number>" } . Anders worden ze gecodeerd als een int. Standaard ingesteld op Onwaar.
  • datetime_representation : de te gebruiken representatie bij het coderen van instanties van datetime.datetime. 0 => {"$date": <dateAsMilliseconds>} , 1 => {"$date": {"$numberLong": "<dateAsMilliseconds>"}} , 2 => {"$date": "<ISO-8601>"}
  • strict_uuid : Indien true, worden het object uuid.UUID gecodeerd naar het strikte modustype Binary van MongoDB Extended JSON. Anders wordt het gecodeerd als {"$uuid": "<hex>" } . Standaard ingesteld op Onwaar.
  • document_class : BSON-documenten geretourneerd door belastingen () worden gedecodeerd naar een instantie van deze klasse. Moet een subklasse van collecties zijn. Standaard ingesteld op dicteren.
  • uuid_representation : de BSON-representatie die moet worden gebruikt bij het coderen en decoderen van instanties van uuid.UUID. Standaard ingesteld op PYTHON_LEGACY.
  • tz_aware : Indien waar, zal het strikte modustype van MongoDB Extended JSON worden gedecodeerd naar tijdzone-bewuste instanties van datetime.datetime. Anders zullen ze naïef zijn. Standaard ingesteld op True.
  • tzinfo : een subklasse datetime.tzinfo die de tijdzone aangeeft van waaruit datetime-objecten moeten worden gedecodeerd. Standaard ingesteld op utc.

Python-bsonjs gebruiken

python-bsonjs is niet afhankelijk van PyMongo en kan een mooie prestatieverbetering bieden ten opzichte van json_util :

bsonjs is ongeveer 10-15x sneller dan json_util van PyMongo bij het decoderen van BSON naar JSON en het coderen van JSON naar BSON.

Let daar op:

  • om bsonjs effectief te gebruiken, is het raadzaam om rechtstreeks met RawBSONDocument te werken
  • datums worden gecodeerd met behulp van de LEGACY-weergave, dwz {"$date": <dateAsMilliseconds>} . Er zijn momenteel geen opties om dat te veranderen.

Installatie

pip install python-bsonjs

Gebruik

Om de bsonjs volledig te benutten, configureert u de database met de klasse RawBSONDocument . Gebruik vervolgens dumps om bson raw bytes om te zetten in json en loads om json om te zetten in bson raw bytes:

import pymongo
import bsonjs
from pymongo import MongoClient
from bson.raw_bson import RawBSONDocument

# configure mongo to use the RawBSONDocument representation
db = pymongo.MongoClient(document_class=RawBSONDocument).samples
# convert json to a bson record
json_record = '{"_id": "some id", "title": "Awesome Movie"}' 
raw_bson = bsonjs.loads(json_record)
bson_record = RawBSONDocument(raw_bson)
# insert the record
result = db.movies.insert_one(bson_record)
print(result.acknowledged)

# find some record
bson_record2 = db.movies.find_one()
# convert the record to json
json_record2 = bsonjs.dumps(bson_record2.raw)
print(json_record2)

De json-module gebruiken met aangepaste handlers

Als u alleen mongoresultaten in json wilt serialiseren, is het mogelijk om de json module te gebruiken, op voorwaarde dat u aangepaste handlers definieert voor het omgaan met niet-serialiseerbare json . Een voordeel is dat u volledige controle hebt over hoe u specifieke velden codeert, zoals de datetime-weergave.

Hier is een handler die datums codeert met de iso-weergave en de id als een hexadecimale tekenreeks:

import pymongo
import json 
import datetime
import bson.objectid

def my_handler(x):
    if isinstance(x, datetime.datetime):
        return x.isoformat()
    elif isinstance(x, bson.objectid.ObjectId):
        return str(x)
    else:
        raise TypeError(x)

db = pymongo.MongoClient().samples
record = db.movies.find_one()
# {u'_id': ObjectId('5692a15524de1e0ce2dfcfa3'), u'title': u'Toy Story 4',
#   u'released': datetime.datetime(2010, 6, 18, 4, 0),}

json_record = json.dumps(record, default=my_handler)
# '{"_id": "5692a15524de1e0ce2dfcfa3", "title": "Toy Story 4", 
#    "released": "2010-06-18T04:00:00"}'


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow