PyMongo
Konvertierung zwischen BSON und JSON
Suche…
Einführung
In vielen Anwendungen müssen Datensätze aus MongoDB im JSON-Format serialisiert werden. Wenn Ihre Datensätze Felder vom Typ Datum, Datum, Uhrzeit, Objekt-ID, Binärcode, Code usw. enthalten, werden bei der Verwendung von json.dumps
TypeError: not JSON serializable
Ausnahmen json.dumps
. Dieses Thema zeigt, wie Sie dieses Problem lösen können.
Json_util verwenden
json_util bietet zwei Hilfsmethoden , dumps
und loads
, die die nativen Json- Methoden umschließen und eine explizite BSON-Konvertierung in und aus Json bereitstellen.
Einfache Benutzung
from bson.json_util import loads, dumps
record = db.movies.find_one()
json_str = dumps(record)
record2 = loads(json_str)
wenn record
ist:
{
"_id" : ObjectId("5692a15524de1e0ce2dfcfa3"),
"title" : "Toy Story 4",
"released" : ISODate("2010-06-18T04:00:00Z")
}
dann wird json_str
:
{
"_id": {"$oid": "5692a15524de1e0ce2dfcfa3"},
"title" : "Toy Story 4",
"released": {"$date": 1276833600000}
}
JSONOptions
Das Verhalten von dumps
über ein JSONOptions
Objekt JSONOptions
werden. Es sind bereits zwei Optionen verfügbar: DEFAULT_JSON_OPTIONS
und 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>)
Um verschiedene Optionen zu verwenden, können Sie:
Ändern Sie das
DEFAULT_JSON_OPTIONS
Objekt. In diesem Fall werden die Optionen für alle nachfolgenden Aufrufe vondumps
:from bson.json_util import DEFAULT_JSON_OPTIONS DEFAULT_JSON_OPTIONS.datetime_representation = 2 dumps(record)
JSONOptions
eineJSONOptions
in einem Aufruf vondumps
mit dem Parameterjson_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)
Die Parameter von JSONOptions
sind:
- strict_number_long : Wenn true, werden Int64-Objekte in den strengen Modustyp NumberLong von MongoDB Extended JSON codiert, dh
{"$numberLong": "<number>" }
. Andernfalls werden sie als int codiert. Standardeinstellung ist "False". - datetime_representation : Die Darstellung, die beim Codieren der Instanzen von datetime.datetime verwendet werden soll. 0 =>
{"$date": <dateAsMilliseconds>}
, 1 =>{"$date": {"$numberLong": "<dateAsMilliseconds>"}}
, 2 =>{"$date": "<ISO-8601>"}
- strict_uuid : Wenn true, werden das uuid.UUID-Objekt im MongoDB Extended JSON-Strict-Modus-Typ Binary codiert. Andernfalls wird es als
{"$uuid": "<hex>" }
codiert. Standardeinstellung ist "False". - document_class : Von load () zurückgegebene BSON-Dokumente werden in eine Instanz dieser Klasse dekodiert. Muss eine Unterklasse von collection.MutableMapping sein. Standardeinstellung zum Diktieren
- uuid_representation : Die BSON-Darstellung, die beim Codieren und Decodieren von Instanzen von uuid.UUID verwendet werden soll. Standardeinstellung ist PYTHON_LEGACY.
- tz_aware : Bei true wird der strikte Modustyp Date von MongoDB Extended JSON in zeitzonenabhängige Instanzen von datetime.datetime dekodiert. Sonst werden sie naiv sein. Standardeinstellung ist "True".
- tzinfo : Eine
datetime.tzinfo
, die die Zeitzone angibt, aus der datetime-Objekte dekodiert werden sollen. Standardeinstellung ist utc.
Python-bsonjs verwenden
python-bsonjs hängt nicht von PyMongo ab und kann eine json_util
Leistungsverbesserung gegenüber json_util
:
bsonjs ist etwa 10-15x schneller als PyMongos json_util bei der Dekodierung von BSON in JSON und der Kodierung von JSON in BSON.
Beachten Sie, dass:
- Um Bsonjs effektiv zu nutzen, wird empfohlen, direkt mit
RawBSONDocument
- Datumsangaben werden mithilfe der LEGACY-Darstellung codiert, dh
{"$date": <dateAsMilliseconds>}
. Derzeit gibt es keine Optionen, um dies zu ändern.
Installation
pip install python-bsonjs
Verwendungszweck
Konfigurieren Sie die Datenbank für die Verwendung der RawBSONDocument
Klasse, um die RawBSONDocument
voll nutzen zu RawBSONDocument
. Verwenden Sie dann dumps
, um bson raw Bytes in json zu konvertieren, und loads
, um json in bson raw Bytes umzuwandeln:
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)
Verwenden des Json-Moduls mit benutzerdefinierten Handlern
Wenn Sie lediglich Mongo-Ergebnisse in json serialisieren möchten, können Sie das json
Modul verwenden, sofern Sie benutzerdefinierte Handler definieren, die mit nicht serialisierbaren Feldtypen umgehen. Ein Vorteil besteht darin, dass Sie die Kodierung bestimmter Felder, wie z. B. die Datetime-Darstellung, voll nutzen können.
Hier ist ein Handler, der Datumsangaben mithilfe der Iso-Darstellung und der ID als Hexadezimalzeichenfolge codiert:
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"}'