Как сериализовать ObjectId с помощью jsonpickle в flask pymongo - PullRequest
0 голосов
/ 25 марта 2020

Я использую Flask с MongoDB в качестве базы данных и Pymon go в качестве драйвера. У меня проблема с сериализацией объекта в JSON с json.dumps(), json.loads(), json_util.dumps() и многими другими, как всегда, 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 тип. Нужен совет, пожалуйста ..

1 Ответ

0 голосов
/ 25 марта 2020

Вот три совета в одном:

  • Чтобы загрузить объект класса в MongoDB, используйте встроенное свойство класса __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"}
...