json_util provides two helper methods, dumps
and loads
, that wrap the native json methods and provide explicit BSON conversion to and from json.
from bson.json_util import loads, dumps
record = db.movies.find_one()
json_str = dumps(record)
record2 = loads(json_str)
if record
is:
{
"_id" : ObjectId("5692a15524de1e0ce2dfcfa3"),
"title" : "Toy Story 4",
"released" : ISODate("2010-06-18T04:00:00Z")
}
then json_str
becomes:
{
"_id": {"$oid": "5692a15524de1e0ce2dfcfa3"},
"title" : "Toy Story 4",
"released": {"$date": 1276833600000}
}
It is possible to customize the behavior of dumps
via a JSONOptions
object. Two sets of options are already available: DEFAULT_JSON_OPTIONS
and 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>)
To use different options, you can:
modify the DEFAULT_JSON_OPTIONS
object. In this case, the options will be used for all subsequent call to dumps
:
from bson.json_util import DEFAULT_JSON_OPTIONS
DEFAULT_JSON_OPTIONS.datetime_representation = 2
dumps(record)
specify a JSONOptions
in a call to dumps
using the json_options
parameter:
# 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)
The parameters of JSONOptions
are:
{"$numberLong": "<number>" }
. Otherwise they will be encoded as an int. Defaults to False.{"$date": <dateAsMilliseconds>}
, 1 => {"$date": {"$numberLong": "<dateAsMilliseconds>"}}
, 2 => {"$date": "<ISO-8601>"}
{"$uuid": "<hex>" }
. Defaults to False.datetime.tzinfo
subclass that specifies the timezone from which datetime objects should be decoded. Defaults to utc.python-bsonjs does not depend on PyMongo and can offer a nice performance improvement over json_util
:
bsonjs is roughly 10-15x faster than PyMongo’s json_util at decoding BSON to JSON and encoding JSON to BSON.
Note that:
RawBSONDocument
{"$date": <dateAsMilliseconds>}
. There is currently no options to change that.pip install python-bsonjs
To take full advantage of the bsonjs, configure the database to use the RawBSONDocument
class. Then, use dumps
to convert bson raw bytes to json and loads
to convert json to 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)
If all you need is serializing mongo results into json, it is possible to use the json
module, provided you define custom handlers to deal with non-serializable fields types.
One advantage is that you have full power on how you encode specific fields, like the datetime representation.
Here is a handler which encodes dates using the iso representation and the id as an hexadecimal string:
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"}'