基本上,架构是这样创建的:
class MyType(graphene.ObjectType):
something = graphene.String()
class Query(graphene.ObjectType):
value = graphene.Field(MyType)
schema = graphene.Schema(query=Query, types=[MyType])
首先,为了添加某种动态,您很可能希望将上面的代码包装在像这样的函数中create_schema()
.
然后,当你想在运行时动态创建一个类时,上面的代码可以这样重写:
def create_schema():
MyType = type('MyType', (graphene.ObjectType,), {
'something': graphene.String(),
})
Query = type('Query', (graphene.ObjectType,), {
'value': graphene.Field(MyType),
})
return graphene.Schema(query=Query, types=[MyType])
对于您的示例,它可能看起来像这样:
def make_resolver(record_name, record_cls):
def resolver(self, info):
data = ...
return record_cls(...)
resolver.__name__ = 'resolve_%s' % record_name
return resolver
def create_schema(db):
record_schemas = {}
for record_type in db.get_record_types():
classname = record_type['id'].title() # 'Author'
fields = {}
for option in record_type['options']:
field_type = {
'text': graphene.String,
...
}[option['type']
fields[option['id']] = field_type() # maybe add label as description?
rec_cls = type(
classname,
(graphene.ObjectType,),
fields,
name=record_type['name'],
description=record_type['desc'],
)
record_schemas[record_type['id']] = rec_cls
# create Query in similar way
fields = {}
for key, rec in record_schemas:
fields[key] = graphene.Field(rec)
fields['resolve_%s' % key] = make_resolver(key, rec)
Query = type('Query', (graphene.ObjectType,), fields)
return graphene.Schema(query=Query, types=list(record_schemas.values()))
请注意,如果您尝试将新字段插入已经存在的类中,
像这样 -MyType.another_field = graphene.String()
,
那么它就不起作用:那是因为当graphene.ObjectType
类被实例化,
它的所有字段都记录在self._meta.fields
有序字典。
并且更新它并不那么简单MyType._meta.fields['another_field'] = thefield
- 请参阅代码graphene.ObjectType.__init_subclass_with_meta__
了解详情。
因此,如果您的架构是动态更改的,那么从头开始完全重新创建它可能比修补它更好。