Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongo嵌入文档不可JSON序列化-Python_Json_Python 3.x_Mongoengine_Graphene Python - Fatal编程技术网

Mongo嵌入文档不可JSON序列化-Python

Mongo嵌入文档不可JSON序列化-Python,json,python-3.x,mongoengine,graphene-python,Json,Python 3.x,Mongoengine,Graphene Python,我目前正在使用石墨烯和MongoEngine。mongo db模式如下所示 class DocumentAModel(Document): id = StringField(required=True) documentB = MapField(EmbeddedDocumentField(DocumentBModel) class DocumentBModel(EmbeddedDocument): id = StringField(required=True)

我目前正在使用石墨烯和MongoEngine。mongo db模式如下所示

class DocumentAModel(Document):
    id = StringField(required=True)
    documentB = MapField(EmbeddedDocumentField(DocumentBModel)

class DocumentBModel(EmbeddedDocument):
    id = StringField(required=True)
    value = IntField()
样本文档如下所示

{
    id: "id_1",
    documentB: {
        0: {
            id: "b_1",
            value: 1
        },
        1: {
            id: "b_2",
            value: 11
        }
    }
class Query(graphene.ObjectType):
    all_document_a = graphene.List(DocumentA)

    def resolve_all_document_a(self, info):
        return list(DocumentAModel.objects.all())
相应地,它们的石墨烯类型是

class DocumentB(MongoengineObjectType):
    class Meta:
        model = DocumentBModel

class DocumentA(MongoengineObjectType):
    class Meta:
        model = DocumentAModel
最后,查询如下所示

{
    id: "id_1",
    documentB: {
        0: {
            id: "b_1",
            value: 1
        },
        1: {
            id: "b_2",
            value: 11
        }
    }
class Query(graphene.ObjectType):
    all_document_a = graphene.List(DocumentA)

    def resolve_all_document_a(self, info):
        return list(DocumentAModel.objects.all())
但是,当我查询allDocumentA以获取文档B时,我得到了错误

DocumentBModel类型的对象不可JSON序列化

我不确定在哪里将文档B封送到json

如果我将DocumentB从
MapField(EmbeddedDocumentField(DocumentBModel)
更改为
DictField()
,它可以正常工作。但是有没有办法使用MapField


感谢

映射字段与DictField类似,只是每个项目的“值”必须与指定的字段类型匹配,并且键必须是字符串类型。 因此,在您的案例中,DocumentModel documentB字段是MapField,值的类型是DocumentBModel。因此,对于DocumentBModel,您需要提供id和值字段。您正在使用graphene创建此字段,但模型映射将与普通(其余)相同drfapiGraphQLAPI。MapField有一些验证,比如key应该是String类型,value应该是模型中提到的类型,但是对于Dictfield,它不需要这样的类型验证,它只是普通的Python字典字段

检查代码片段。并根据需要更改Graphene查询和模式

检查以下代码:

class DocumentBModel(fields.EmbeddedDocument):
id=fields.StringField(必需=True)
value=fields.IntField()
类文档模型(文档):
name=fields.StringField(必需=True)
documentB=fields.MapField(fields.EmbeddedDocumentField(DocumentBModel))
Django shell
$python manage.py shell
>>>
>>>B_obj1=DocumentBModel(**{'id':'B_1','value':1})
>>>B_obj2=DocumentBModel(**{'id':'B_2','value':2})
>>>data_obj=documentModel.objects.create(**{“name”:“akash”,“documentB”:{“0”:B_obj1,“1”:B_obj2})
>>>数据对象数据
{'id':ObjectId('5ebd1d2cf549becd5a462924'),'name':'akash','documentB':{'0':,'1':}
数据库条目:

{
“_id”:ObjectId(“5ebd1d2cf549becd5a462924”),
“名称”:“阿卡什”,
“文件B”:{
"0" : {
“id”:“b_1”,
“价值”:1
},
"1" : {
“id”:“b_2”,
“价值”:2
}
}
}

映射字段与DictField类似,只是每个项目的“值”必须与指定的字段类型匹配,并且键必须是字符串类型。 因此,在您的案例中,DocumentModel documentB字段是MapField,值的类型是DocumentBModel。因此,对于DocumentBModel,您需要提供id和值字段。您正在使用graphene创建此字段,但模型映射将与普通(其余)相同drfapiGraphQLAPI。MapField有一些验证,比如key应该是String类型,value应该是模型中提到的类型,但是对于Dictfield,它不需要这样的类型验证,它只是普通的Python字典字段

检查代码片段。并根据需要更改Graphene查询和模式

检查以下代码:

class DocumentBModel(fields.EmbeddedDocument):
id=fields.StringField(必需=True)
value=fields.IntField()
类文档模型(文档):
name=fields.StringField(必需=True)
documentB=fields.MapField(fields.EmbeddedDocumentField(DocumentBModel))
Django shell
$python manage.py shell
>>>
>>>B_obj1=DocumentBModel(**{'id':'B_1','value':1})
>>>B_obj2=DocumentBModel(**{'id':'B_2','value':2})
>>>data_obj=documentModel.objects.create(**{“name”:“akash”,“documentB”:{“0”:B_obj1,“1”:B_obj2})
>>>数据对象数据
{'id':ObjectId('5ebd1d2cf549becd5a462924'),'name':'akash','documentB':{'0':,'1':}
数据库条目:

{
“_id”:ObjectId(“5ebd1d2cf549becd5a462924”),
“名称”:“阿卡什”,
“文件B”:{
"0" : {
“id”:“b_1”,
“价值”:1
},
"1" : {
“id”:“b_2”,
“价值”:2
}
}
}

我认为问题在于graphql要求响应对象具有明确的结构。将dict或map作为属性会“混淆”graphql

在上面的示例中,查询可以是

query {
    documentA {
        id
        documentB {
            0 {
                id
                value
            }
            1 {
                id
                value
            }
        }
    }
}
但是documentB没有任何属性0和1。因此它只能是一个dict列表。在这种情况下,查询将变为

query {
    documentA {
        id
        documentB {
            id
            value
        }
    }
}

我认为问题在于graphql要求响应对象具有明确的结构。将dict或map作为属性会“混淆”graphql

在上面的示例中,查询可以是

query {
    documentA {
        id
        documentB {
            0 {
                id
                value
            }
            1 {
                id
                value
            }
        }
    }
}
但是documentB没有任何属性0和1。因此它只能是一个dict列表。在这种情况下,查询将变为

query {
    documentA {
        id
        documentB {
            id
            value
        }
    }
}

MapField类似于DictField,只是每个项的“值”必须与指定的字段类型相匹配。是的,我希望将值强制为DocumentB类型,但存在相同的问题。有些进展?是的,我认为问题是因为graphql要求响应对象具有明确的结构。将dict或map作为属性在上面的例子中,查询可以是查询{docta{id documentB{0{id value}1{id value}}}但是documentB没有任何属性0和1。因此它只能是一个DICT列表。希望helpsMapField类似于DictField,只是每个项的“值”必须与指定的字段类型匹配。是的,我希望将该值强制为documentB类型,具有相同的问题。S