【问题标题】:GraphQL circular queries with one to many relationships具有一对多关系的 GraphQL 循环查询
【发布时间】:2018-10-02 18:43:13
【问题描述】:

我正在通过构建一个简单的 python 应用程序来学习 GraphQL,基本上运行 nmap 扫描将输出存储到数据库,并且可以通过 GraphQL API 进行查询。我似乎对 GraphQL 的工作原理有点困惑。

我有几个表是一对多关系:user has many scansscans have resultsresults have hostshosts have portshosts have os。我使用sqlalchemy 定义并使用graphene

现在,在我的 GraphQL 架构中,我有:

class Scans(SQLAlchemyObjectType):
    class Meta:
        model = ScansModel


class ScanResult(SQLAlchemyObjectType):
    class Meta:
        model = ScanResultModel


class Hosts(SQLAlchemyObjectType):
    class Meta:
        model = HostInfoModel


class Ports(SQLAlchemyObjectType):
    class Meta:
        model = PortInfoModel


class Os(SQLAlchemyObjectType):
    class Meta:
        model = OsInfoModel

class Query(graphene.ObjectType):
    user = graphene.Field(User)
    scans = graphene.List(Scans)
    scan_results = graphene.List(ScanResult)
    hosts = graphene.List(Hosts)
    ports = graphene.List(Ports)
    os = graphene.Field(Os)

    def resolve_scans(self, info):
        query = Scans.get_query(info)
        return query

现在,当我进行 GraphQL 查询时,我可以查询扫描、结果、主机信息、端口信息、osinfo,而无需为这些字段使用解析器。我的印象是这些字段中的每一个都需要一个解析器。

此外,由于外键和关系表,我似乎能够进行循环查询(所以从scanresults 我可以查询scans,从scans 我可以查询user)。

这是正确的行为,还是误解了 GraphQL 的工作原理?

【问题讨论】:

    标签: graphql graphene-python


    【解决方案1】:

    你需要做的是:

    
    class ScanResult(SQLAlchemyObjectType):
        class Meta:
            model = ScanResultModel
    
        scans = graphene.List(Scans, description="Scans from results.")
    
        def resolve_scans(self, info):
            query = Scans.get_query(info)
            return query.filter(ScansModel.my_id == self.scans_id).all()
    
    

    这可能使您能够构建如下查询:

    {
      scanresult{
        edges {
          node {
             id
             scans{
                id
             }
          }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我知道每个带有 SQLAlchemyObjecType 的字段的解析器都是在库中处理的。

      当我使用 mongoengine 而不使用 MongoengineObjectType 时,我的代码是这样的。

      class Query(graphene.ObjectType):
      
          department = graphene.List(of_type=DepartmentField,
                                 name=graphene.String(default_value="all"))
      
          role = graphene.List(of_type=RoleField,
                           name=graphene.String(default_value="all"))
      
          employee = graphene.List(of_type=EmployeeField,
                               name=graphene.String(default_value="all"))
      
          def resolve_department(self, info, name):
              if name == "all":
                  department = [construct(DepartmentField, object) for object in DepartmentModel.objects]
                  return department
              else:
                  department = DepartmentModel.objects.get(name=name)
                  return [construct(DepartmentField, department)]
      
          def resolve_role(self, info, name):
                  .
                  .
                  .
      

      【讨论】:

        猜你喜欢
        • 2019-01-31
        • 1970-01-01
        • 2021-01-13
        • 2019-06-06
        • 2023-03-14
        • 1970-01-01
        • 2021-10-21
        • 1970-01-01
        相关资源
        最近更新 更多