How can I serialize a MongoDB ObjectId with Marshmallow?

喜你入骨 提交于 2019-12-12 07:59:15

问题


I'm building and API on top of Flask using marshmallow and mongoengine. When I make a call and an ID is supposed to be serialized I receive the following error:

TypeError: ObjectId('54c117322053049ba3ef31f3') is not JSON serializable

I saw some ways with other libraries to override the way the ObjectId is treated. I haven't figured it out with Marshmallow yet, does anyone know how to do that?

My model is:

class Process(db.Document):
    name = db.StringField(max_length=255, required=True, unique=True)
    created_at = db.DateTimeField(default=datetime.datetime.now, required=True)

My serializer:

class ProcessSerializer(Serializer):
    class Meta:
        fields = ("id", "created_at", "name")

And the view:

class ProcessView(Resource):
    def get(self, id):
        process = Process.objects.get_or_404(id)
        return ProcessSerializer(process).data

回答1:


When you just pass Meta.fields to a schema, Marshmallow tries to pick a field type for each attribute. Since it doesn't know what an ObjectId is, it just passes it on to the serialized dict. When you try to dump this to JSON, it doesn't know what an ObjectId is and raises an error. To solve this, you need to tell Marshmallow what field to use for the id. A BSON ObjectId can be converted to a string, so use a String field.

from marshmallow import Schema, fields

class ProcessSchema(Schema):
    id = fields.String()

    class Meta:
        additional =  ('created_at', 'name')

You can also tell Marshmallow what field to use for the ObjectId type so that you don't have to add the field each time.

from bson import ObjectId
from marshmallow import Schema, fields

Schema.TYPE_MAPPING[ObjectId] = fields.String



回答2:


marshmallow-mongoengine does this:

Marshmallow-Mongoengine is about bringing together a Mongoengine Document with a Marshmallow Schema.

import marshmallow_mongoengine as ma


class ProcessSchema(ma.ModelSchema):
    class Meta:
        model = Process

It has an ObjectId field that serializes/deserializes ObjectIds.



来源:https://stackoverflow.com/questions/28093824/how-can-i-serialize-a-mongodb-objectid-with-marshmallow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!