PyMongo
BSON과 JSON 간의 변환
수색…
소개
많은 응용 프로그램에서 MongoDB의 레코드를 JSON 형식으로 serialize해야합니다. 레코드에 date, datetime, objectId, binary, code 등의 필드가있는 경우 json.dumps
사용할 때 TypeError: not JSON serializable
예외가 TypeError: not JSON serializable
가 발생합니다. 이 주제는이를 극복하는 방법을 보여줍니다.
json_util 사용하기
json_util 은 네이티브 json 메서드를 랩핑하고 json과의 명시적인 BSON 변환을 제공하는 두 가지 도우미 메서드, dumps
및 loads
제공합니다.
간단한 사용법
from bson.json_util import loads, dumps
record = db.movies.find_one()
json_str = dumps(record)
record2 = loads(json_str)
record
이있는 경우 :
{
"_id" : ObjectId("5692a15524de1e0ce2dfcfa3"),
"title" : "Toy Story 4",
"released" : ISODate("2010-06-18T04:00:00Z")
}
json_str
는 다음과 같습니다.
{
"_id": {"$oid": "5692a15524de1e0ce2dfcfa3"},
"title" : "Toy Story 4",
"released": {"$date": 1276833600000}
}
JSONOptions
JSONOptions
객체를 통해 dumps
의 동작을 사용자 정의 할 수 있습니다. DEFAULT_JSON_OPTIONS
및 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>)
다른 옵션을 사용하려면 다음을 수행 할 수 있습니다.
DEFAULT_JSON_OPTIONS
오브젝트를 수정하십시오. 이 경우 옵션은 이후의 모든dumps
호출에 사용됩니다.from bson.json_util import DEFAULT_JSON_OPTIONS DEFAULT_JSON_OPTIONS.datetime_representation = 2 dumps(record)
json_options
매개 변수를 사용하여dumps
호출에서JSONOptions
를 지정하십시오.# 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)
JSONOptions
의 매개 변수는 JSONOptions
과 같습니다.
- strict_number_long : true 인 경우 Int64 객체는 MongoDB Extended JSON의 Strict 모드 유형 인 NumberLong, 즉
{"$numberLong": "<number>" }
로 인코딩됩니다. 그렇지 않은 경우, int로서 encode됩니다. 기본값은 False입니다. - datetime_representation : datetime.datetime의 인스턴스를 인코딩 할 때 사용할 표현입니다. 0 =>
{"$date": <dateAsMilliseconds>}
1 =>{"$date": {"$numberLong": "<dateAsMilliseconds>"}}
2 =>{"$date": "<ISO-8601>"}
- strict_uuid : true이면 uuid.UUID 객체는 MongoDB Extended JSON의 Strict 모드 유형 Binary로 인코딩됩니다. 그렇지 않으면
{"$uuid": "<hex>" }
로 인코딩됩니다. 기본값은 False입니다. - document_class : loads ()에 의해 반환 된 BSON 문서는이 클래스의 인스턴스로 디코드됩니다. collections.MutableMapping의 서브 클래스 여야합니다. 기본값은 dict입니다.
- uuid_representation : uuid.UUID의 인스턴스를 인코딩 및 디코딩 할 때 사용할 BSON 표현입니다. 기본값은 PYTHON_LEGACY입니다.
- tz_aware : true이면 MongoDB Extended JSON의 Strict 모드 유형 Date가 datetime.datetime의 시간대 인식 인스턴스로 디코딩됩니다. 그렇지 않으면 그들은 순진 할 것이다. True로 기본값.
- tzinfo : datetime 객체를 디코딩해야하는 시간대를 지정하는
datetime.tzinfo
하위 클래스입니다. 기본값은 utc입니다.
python-bsonjs 사용하기
python-bsonjs 는 PyMongo에 의존하지 않고 json_util보다 json_util
성능 향상을 제공 할 수 있습니다.
bsonjs 는 BSON을 JSON으로 디코딩하고 JSON을 BSON으로 인코딩 할 때 PyMongo의 json_util보다 약 10-15 배 빠릅니다.
참고 사항 :
- 효과적으로 bsonjs를 사용하기 위해서는 직접 작업하는 것이 좋습니다
RawBSONDocument
- 날짜는 LEGACY 표현 즉
{"$date": <dateAsMilliseconds>}
사용하여 인코딩됩니다. 현재이 옵션을 변경할 수있는 옵션이 없습니다.
설치
pip install python-bsonjs
용법
bsonjs를 최대한 활용하려면 RawBSONDocument
클래스를 사용하도록 데이터베이스를 구성하십시오. 그런 다음, 사용은 dumps
원시 JSON으로 바이트 bson 변환 loads
원시 바이트를 bson하는 JSON 변환 :
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)
커스텀 핸들러와 함께 json 모듈 사용하기
mongo 결과를 json으로 직렬화하는 것이 필요한 경우 직렬화 할 수없는 필드 유형을 처리하기 위해 사용자 정의 핸들러를 정의한 경우 json
모듈을 사용할 수 있습니다. 한 가지 장점은 datetime 표현과 같이 특정 필드를 인코딩하는 방법에 전적인 힘을 얻는 것입니다.
다음은 iso 표현과 id를 16 진수 문자열로 사용하여 날짜를 인코딩하는 핸들러입니다.
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"}'