Python Graphene Interface + InlineFragment 似乎无法解析 ObjectType 字段
Python Graphene Interface + InlineFragment seems doesn't resolve ObjectType fields
我尝试在从接口继承的 ObjectType 上使用 InlineFragment 解析 ObjectType 字段,但它似乎不起作用。
这是我的架构:
@schema.register
class BundleInterface(graphene.Interface):
id = graphene.ID()
identifier = graphene.String()
name = graphene.String()
publication_date = DateTime()
articles = graphene.List('Article')
def resolve_articles(self, args, info):
info_parser = InfoParser('Article', info)
return self.articles.options(load_only(*info_parser.root_fields)).all()
@classmethod
def _resolve_type(cls, schema, instance, *args):
if instance.mid is not None:
return Issue.internal_type(schema)
return Bundle.internal_type(schema)
@schema.register
class Bundle(BundleInterface):
pass
@schema.register
class Issue(BundleInterface):
mid = graphene.String()
cover = graphene.Field('Image')
pages = graphene.List('Page')
def resolve_cover(self, args, info):
pass
def resolve_pages(self, args, info):
return self.pages['pages']
这是我的查询:
class Query(graphene.ObjectType):
bundle = graphene.Field('BundleInterface', identifier=graphene.String())
def resolve_bundle(self, args, info):
info_parser = InfoParser('BundleInterface', info)
filters = {}
filters[object_type_to_model['BundleInterface']['fields']['identifier']] = args.get('identifier')
return info_parser.root_model.query.filter_by(**filters)\
.options(load_only(*info_parser.root_fields))\
.one()
这是我的sql炼金术模型:
class Bundle(Base):
__tablename__ = 'bundle'
bundle_id = Column(Integer, primary_key=True)
identifier = Column(UUID(as_uuid=True))
name = Column(String)
publication_date = Column(DateTime)
mid = Column(UUID(as_uuid=True))
pages = Column(JSONB)
source_id = Column(Integer, ForeignKey('source.source_id'))
这是我在 graphiql 中的查询:
{
bundle(identifier: "30752cba-f3a7-49c8-b6c7-afa6a9579a1c") {
name
... on Issue {
mid
}
}
}
这是我的结果:
{
"data": {
"bundle": {
"name": "bundle 1"
}
}
}
我确信 BundleInterface 的 _resolve_type 方法 return 是一个 Issue ObjectType(因为我已经打印了它)但是在那之后我不知道为什么 Issue ObjectType 没有被解决。
我也知道使用 sqlalchemy 从 postgresql 获取的数据包含 Issue ObjectType 需要自行解决的数据,因为我在 flask 日志中看到发送到 psotgre 的 sql 请求sql.
这是 sql 请求:
[2016-06-16 20:03:14,588: INFO / sqlalchemy.engine.base.Engine] BEGIN (implicit)
[2016-06-16 20:03:14,589: INFO / sqlalchemy.engine.base.Engine] SELECT bundle.bundle_id AS bundle_bundle_id, bundle.name AS bundle_name, bundle.mid AS bundle_mid
FROM bundle
WHERE bundle.identifier = %(identifier_1)s
[2016-06-16 20:03:14,589: INFO / sqlalchemy.engine.base.Engine] {'identifier_1': '30752cba-f3a7-49c8-b6c7-afa6a9579a1c'}
我们可以看到 mid 属性的数据是从 potsgresql 中获取的,因此数据可供 Issue ObjectType 自行解析。
但是 sqlalchemy return Bundle 实例列表,我想解决一个问题 ObjectType,也许它不起作用,但我不确定 Bundle ObjectType 是否成功使用 Bundle sqlalchemy 实例解析自身。
此外,graphiql 界面中没有显示任何错误。
不知道这种模式的实现方式是否正确?
你有办法解决我的问题吗?
我发现了问题。我在 graphql-core 上发出了拉取请求:https://github.com/graphql-python/graphql-core/pull/68
我尝试在从接口继承的 ObjectType 上使用 InlineFragment 解析 ObjectType 字段,但它似乎不起作用。
这是我的架构:
@schema.register
class BundleInterface(graphene.Interface):
id = graphene.ID()
identifier = graphene.String()
name = graphene.String()
publication_date = DateTime()
articles = graphene.List('Article')
def resolve_articles(self, args, info):
info_parser = InfoParser('Article', info)
return self.articles.options(load_only(*info_parser.root_fields)).all()
@classmethod
def _resolve_type(cls, schema, instance, *args):
if instance.mid is not None:
return Issue.internal_type(schema)
return Bundle.internal_type(schema)
@schema.register
class Bundle(BundleInterface):
pass
@schema.register
class Issue(BundleInterface):
mid = graphene.String()
cover = graphene.Field('Image')
pages = graphene.List('Page')
def resolve_cover(self, args, info):
pass
def resolve_pages(self, args, info):
return self.pages['pages']
这是我的查询:
class Query(graphene.ObjectType):
bundle = graphene.Field('BundleInterface', identifier=graphene.String())
def resolve_bundle(self, args, info):
info_parser = InfoParser('BundleInterface', info)
filters = {}
filters[object_type_to_model['BundleInterface']['fields']['identifier']] = args.get('identifier')
return info_parser.root_model.query.filter_by(**filters)\
.options(load_only(*info_parser.root_fields))\
.one()
这是我的sql炼金术模型:
class Bundle(Base):
__tablename__ = 'bundle'
bundle_id = Column(Integer, primary_key=True)
identifier = Column(UUID(as_uuid=True))
name = Column(String)
publication_date = Column(DateTime)
mid = Column(UUID(as_uuid=True))
pages = Column(JSONB)
source_id = Column(Integer, ForeignKey('source.source_id'))
这是我在 graphiql 中的查询:
{
bundle(identifier: "30752cba-f3a7-49c8-b6c7-afa6a9579a1c") {
name
... on Issue {
mid
}
}
}
这是我的结果:
{
"data": {
"bundle": {
"name": "bundle 1"
}
}
}
我确信 BundleInterface 的 _resolve_type 方法 return 是一个 Issue ObjectType(因为我已经打印了它)但是在那之后我不知道为什么 Issue ObjectType 没有被解决。
我也知道使用 sqlalchemy 从 postgresql 获取的数据包含 Issue ObjectType 需要自行解决的数据,因为我在 flask 日志中看到发送到 psotgre 的 sql 请求sql.
这是 sql 请求:
[2016-06-16 20:03:14,588: INFO / sqlalchemy.engine.base.Engine] BEGIN (implicit)
[2016-06-16 20:03:14,589: INFO / sqlalchemy.engine.base.Engine] SELECT bundle.bundle_id AS bundle_bundle_id, bundle.name AS bundle_name, bundle.mid AS bundle_mid
FROM bundle
WHERE bundle.identifier = %(identifier_1)s
[2016-06-16 20:03:14,589: INFO / sqlalchemy.engine.base.Engine] {'identifier_1': '30752cba-f3a7-49c8-b6c7-afa6a9579a1c'}
我们可以看到 mid 属性的数据是从 potsgresql 中获取的,因此数据可供 Issue ObjectType 自行解析。
但是 sqlalchemy return Bundle 实例列表,我想解决一个问题 ObjectType,也许它不起作用,但我不确定 Bundle ObjectType 是否成功使用 Bundle sqlalchemy 实例解析自身。
此外,graphiql 界面中没有显示任何错误。
不知道这种模式的实现方式是否正确?
你有办法解决我的问题吗?
我发现了问题。我在 graphql-core 上发出了拉取请求:https://github.com/graphql-python/graphql-core/pull/68