如何在 flask pymongo 中使用 jsonpickle 序列化 ObjectId
How to serialize ObjectId with jsonpickle in flask pymongo
我使用 Flask MongoDB 作为数据库,使用 pymongo 作为驱动程序。我在使用 json.dumps()
、json.loads()
、json_util.dumps()
将对象序列化为 JSON 时遇到了问题,因为它总是说 TypeError: Object of type 'EachRoom' is not JSON serializable
。我找到了一个名为 jsonpickle
的库来将对象序列化为 JSON。除 ObjectId
字段外,一切都按预期完成。当我检查数据类型时,它显示为 bytes
类型。这是我的代码:
class EachRoom:
def __init__(self, id, rooms):
self.id = id
self.rooms = rooms
class Room(object):
@classmethod
def return_all_by_user(cls):
cursor_user = mongo.db.rooms.distinct('user_id')
users = []
for row in cursor_user:
print(str(row))
cursor_room = mongo.db.rooms.find({'user_id': ObjectId(row)})
each = EachRoom(ObjectId(row), cursor_room)
users.append(each)
print(cursor_room)
print(users)
user = jsonpickle.encode(users, unpicklable=False)
res_user = jsonpickle.decode(user)
print(res_user)
if cursor_room:
return Response(
json_util.dumps({'message': 'success', 'user': res_user}, json_options=json_util.RELAXED_JSON_OPTIONS),
mimetype='application/json'
)
else:
return {'message': 'Document rooms is empty'}, 404
这是回复:
{
"message": "success",
"user": [
{
"id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
},
"rooms": [
{
"_id": {
"$binary": {
"base64": "XngkNuL9Y6AIX04v",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:34.789000",
"name": "Ruang Makan",
"updated_at": "2020-03-23 09:51:34.789000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "XngkROL9Y6AIX04w",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:48.834000",
"name": "Kamar Mandi",
"updated_at": "2020-03-23 09:51:48.834000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "XngkTOL9Y6AIX04x",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:56.220000",
"name": "Kamar Tidur Utama",
"updated_at": "2020-03-23 09:51:56.220000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
}
]
},
{
"id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
},
"rooms": [
{
"_id": {
"$binary": {
"base64": "Xnq+2G5/pNeS7ynf",
"subType": "00"
}
},
"created_at": "2020-03-25 09:15:52.819000",
"name": "Kamar Tidur Eren",
"updated_at": "2020-03-25 09:15:52.819000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "Xnq+6W5/pNeS7yng",
"subType": "00"
}
},
"created_at": "2020-03-25 09:16:09.683000",
"name": "Kamar Tidur Utama",
"updated_at": "2020-03-25 09:16:09.683000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "Xnq+8G5/pNeS7ynh",
"subType": "00"
}
},
"created_at": "2020-03-25 09:16:16.262000",
"name": "Kamar Mandi",
"updated_at": "2020-03-25 09:16:16.262000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
}
]
}
]
}
唯一出错的是 id
、user_id
和 _id
作为 ObjectId
类型。需要建议..
三合一提示:
- 要将 class 对象加载到 MongoDB,请使用 class 的内置
__dict__
属性.
- 要将你的 BSON 变成 JSON 使用来自
bson.json_util
模块的转储
- 最后避免使用
id
作为变量;这是一个 python 函数。
这里有一个小样本可以尝试:
from pymongo import MongoClient
from bson import ObjectId
from bson.json_util import dumps
db = MongoClient()['mydatabase']
class EachRoom:
def __init__(self, room_id, rooms):
self.id = room_id
self.rooms = rooms
room1 = EachRoom(ObjectId("123456789012345678901234"), '1')
db.rooms.insert_one(room1.__dict__)
print(dumps(db.rooms.find_one()))
给出:
{"_id": {"$oid": "5e7b8d7ebf681e2e5ecb6059"}, "id": {"$oid": "123456789012345678901234"}, "rooms": "1"}
我使用 Flask MongoDB 作为数据库,使用 pymongo 作为驱动程序。我在使用 json.dumps()
、json.loads()
、json_util.dumps()
将对象序列化为 JSON 时遇到了问题,因为它总是说 TypeError: Object of type 'EachRoom' is not JSON serializable
。我找到了一个名为 jsonpickle
的库来将对象序列化为 JSON。除 ObjectId
字段外,一切都按预期完成。当我检查数据类型时,它显示为 bytes
类型。这是我的代码:
class EachRoom:
def __init__(self, id, rooms):
self.id = id
self.rooms = rooms
class Room(object):
@classmethod
def return_all_by_user(cls):
cursor_user = mongo.db.rooms.distinct('user_id')
users = []
for row in cursor_user:
print(str(row))
cursor_room = mongo.db.rooms.find({'user_id': ObjectId(row)})
each = EachRoom(ObjectId(row), cursor_room)
users.append(each)
print(cursor_room)
print(users)
user = jsonpickle.encode(users, unpicklable=False)
res_user = jsonpickle.decode(user)
print(res_user)
if cursor_room:
return Response(
json_util.dumps({'message': 'success', 'user': res_user}, json_options=json_util.RELAXED_JSON_OPTIONS),
mimetype='application/json'
)
else:
return {'message': 'Document rooms is empty'}, 404
这是回复:
{
"message": "success",
"user": [
{
"id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
},
"rooms": [
{
"_id": {
"$binary": {
"base64": "XngkNuL9Y6AIX04v",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:34.789000",
"name": "Ruang Makan",
"updated_at": "2020-03-23 09:51:34.789000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "XngkROL9Y6AIX04w",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:48.834000",
"name": "Kamar Mandi",
"updated_at": "2020-03-23 09:51:48.834000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "XngkTOL9Y6AIX04x",
"subType": "00"
}
},
"created_at": "2020-03-23 09:51:56.220000",
"name": "Kamar Tidur Utama",
"updated_at": "2020-03-23 09:51:56.220000",
"user_id": {
"$binary": {
"base64": "Xl/WQvzhBgBTGeiE",
"subType": "00"
}
}
}
]
},
{
"id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
},
"rooms": [
{
"_id": {
"$binary": {
"base64": "Xnq+2G5/pNeS7ynf",
"subType": "00"
}
},
"created_at": "2020-03-25 09:15:52.819000",
"name": "Kamar Tidur Eren",
"updated_at": "2020-03-25 09:15:52.819000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "Xnq+6W5/pNeS7yng",
"subType": "00"
}
},
"created_at": "2020-03-25 09:16:09.683000",
"name": "Kamar Tidur Utama",
"updated_at": "2020-03-25 09:16:09.683000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
},
{
"_id": {
"$binary": {
"base64": "Xnq+8G5/pNeS7ynh",
"subType": "00"
}
},
"created_at": "2020-03-25 09:16:16.262000",
"name": "Kamar Mandi",
"updated_at": "2020-03-25 09:16:16.262000",
"user_id": {
"$binary": {
"base64": "XnYgKnLe9u63KLbG",
"subType": "00"
}
}
}
]
}
]
}
唯一出错的是 id
、user_id
和 _id
作为 ObjectId
类型。需要建议..
三合一提示:
- 要将 class 对象加载到 MongoDB,请使用 class 的内置
__dict__
属性. - 要将你的 BSON 变成 JSON 使用来自
bson.json_util
模块的转储 - 最后避免使用
id
作为变量;这是一个 python 函数。
这里有一个小样本可以尝试:
from pymongo import MongoClient
from bson import ObjectId
from bson.json_util import dumps
db = MongoClient()['mydatabase']
class EachRoom:
def __init__(self, room_id, rooms):
self.id = room_id
self.rooms = rooms
room1 = EachRoom(ObjectId("123456789012345678901234"), '1')
db.rooms.insert_one(room1.__dict__)
print(dumps(db.rooms.find_one()))
给出:
{"_id": {"$oid": "5e7b8d7ebf681e2e5ecb6059"}, "id": {"$oid": "123456789012345678901234"}, "rooms": "1"}