Python Graphene接口+ InlineFragment似乎无法解析ObjectType字段

时间:2016-06-17 08:44:59

标签: python interface sqlalchemy graphenedb

我尝试在从接口继承的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()

这是我的sqlalchemy模型:

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方法返回一个Issue ObjectType(因为我打印了它)但之后我不知道为什么没有解决Issue ObjectType。

我也知道使用sqlalchemy从postgresql获取的数据包含Issue ObjectType需要自行解析的数据,因为我在flask日志中看到发送到psotgresql的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'}

我们可以看到中间属性的数据是从potgresql获取的,因此可以使用Issue ObjectType来解析自己的数据。

但sqlalchemy返回一个Bundle实例列表,我想解决一个问题ObjectType,也许它不能解决问题,但我不确定Bundle ObjectType是否能成功解决自己的Bundle sqlalchemy实例。

此外,graphiql界面中没有显示任何错误。

我不知道这是否是实施此模式的正确方法?

你有什么想法解决我的问题吗?

1 个答案:

答案 0 :(得分:1)

我发现了这个问题。我在graphql-core上发出了一个pull请求:https://github.com/graphql-python/graphql-core/pull/68