Mongo嵌入文档不可JSON序列化-Python
我目前正在使用石墨烯和MongoEngine。mongo db模式如下所示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)
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创建此字段,但模型映射将与普通(其余)相同drfapi和GraphQLAPI。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创建此字段,但模型映射将与普通(其余)相同drfapi和GraphQLAPI。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