如何使用Marshmallow序列化MongoDB ObjectId?

时间:2023-01-27 16:33:33

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:

我正在使用棉花糖和mongoengine在Flask上构建和API。当我打电话并且ID应该被序列化时,我收到以下错误:

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?

我看到了其他库的一些方法来覆盖ObjectId的处理方式。我还没有想到Marshmallow,有谁知道怎么做?

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

2 个解决方案

#1


10  

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.

当您将Meta.fields传递给模式时,Marshmallow会尝试为每个属性选择一个字段类型。由于它不知道ObjectId是什么,它只是将它传递给序列化的dict。当您尝试将其转储到JSON时,它不知道ObjectId是什么并引发错误。要解决这个问题,您需要告诉Marshmallow要用于id的字段。 BSON ObjectId可以转换为字符串,因此请使用String字段。

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.

您还可以告诉Marshmallow对ObjectId类型使用哪个字段,这样您就不必每次都添加字段。

from bson import ObjectId
from marshmallow import Schema, fields

Schema.TYPE_MAPPING[ObjectId] = fields.String

#2


2  

marshmallow-mongoengine does this:

棉花糖 - mongoengine这样做:

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

Marshmallow-Mongoengine是关于将Mongoengine文件与棉花糖模式结合在一起的。

import marshmallow_mongoengine as ma


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

It has an ObjectId field that serializes/deserializes ObjectIds.

它有一个ObjectId字段,用于序列化/反序列化ObjectIds。

#1


10  

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.

当您将Meta.fields传递给模式时,Marshmallow会尝试为每个属性选择一个字段类型。由于它不知道ObjectId是什么,它只是将它传递给序列化的dict。当您尝试将其转储到JSON时,它不知道ObjectId是什么并引发错误。要解决这个问题,您需要告诉Marshmallow要用于id的字段。 BSON ObjectId可以转换为字符串,因此请使用String字段。

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.

您还可以告诉Marshmallow对ObjectId类型使用哪个字段,这样您就不必每次都添加字段。

from bson import ObjectId
from marshmallow import Schema, fields

Schema.TYPE_MAPPING[ObjectId] = fields.String

#2


2  

marshmallow-mongoengine does this:

棉花糖 - mongoengine这样做:

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

Marshmallow-Mongoengine是关于将Mongoengine文件与棉花糖模式结合在一起的。

import marshmallow_mongoengine as ma


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

It has an ObjectId field that serializes/deserializes ObjectIds.

它有一个ObjectId字段,用于序列化/反序列化ObjectIds。