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:

  1. Ändern Sie das DEFAULT_JSON_OPTIONS Objekt. In diesem Fall werden die Optionen für alle nachfolgenden Aufrufe von dumps :

     from bson.json_util import DEFAULT_JSON_OPTIONS
     DEFAULT_JSON_OPTIONS.datetime_representation = 2
     dumps(record)
    
  2. JSONOptions eine JSONOptions in einem Aufruf von dumps mit dem 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)
    

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


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow