return 来自石墨烯 (graphql) 变异的用户定义数据结构

return user-defined data structure from graphene (graphql) mutation

我有一个突变,我想 return 任意形状的数据,但我很难想象如何通过 graphene 突变来做到这一点。

我想要return这样的数据:

{
    "foo": {
        "success": [
            {
                "id": "abc123",
                "goober": {
                    "success": [
                        {
                            "id": "goober-type-1",
                            "baz": "blahblahblah"
                        },
                        {
                            "id": "goober-type-2",
                            "baz": "blahblahblah"
                        }
                    ],
                    "failed": [],
                    "cancelled": []
                },
                "tronic": {
                    "success": [
                        {
                            "id": "tronic-type-1",
                            "baz": "blahblahblah"
                        },
                        {
                            "id": "tronic-type-2",
                            "baz": "blahblahblah"
                        }
                    ],
                    "failed": [],
                    "cancelled": []
                }
            }
        ],
        "failed": [
            {
                "id": "abc123",
                "goober": {
                    "success": [],
                    "failed": [
                        {
                            "id": "goober-type-3",
                            "baz": "blahblahblah"
                        }
                    ],
                    "cancelled": [
                        {
                            "id": "goober-type-4",
                            "baz": "blahblahblah"
                        }
                    ]
                },
                "tronic": {
                    "success": [],
                    "failed": [
                        {
                            "id": "tronic-type-4",
                            "baz": "blahblahblah"
                        }
                    ],
                    "cancelled": [
                        {
                            "id": "tronic-type-3",
                            "baz": "blahblahblah"
                        }
                    ]
                }
            }
        ]
    }
}

我的直觉是想用这样的方式定义 graphene.ObjectType

class Goober(graphene.ObjectType):
    id = graphene.String()
    baz = graphene.String()

class Tronic(graphene.ObjectType):
    id = graphene.String()
    baz = graphene.String()

class Foo(graphene.ObjectType):

    id = graphene.String()
    goober = graphene.ObjectType(
        success = graphene.List(Goober),
        failed = graphene.List(Goober),
        cancelled = graphene.List(Goober)
    )
    tronic = graphene.ObjectType(
        success = graphene.List(Tronic),
        failed = graphene.List(Tronic),
        cancelled = graphene.List(Tronic)
    )

class Results(graphene.ObjectType):
    foo = graphene.ObjectType(
        success=graphene.List(Foo),
        failed=graphene.List(Foo)
    )

但我真的没有用这种方法取得任何进展,感觉我从根本上误解了一些东西。

我在其他领域取得了成功,returning SQL 对象和一些自定义对象,但在生成和 returning 相对复杂的嵌套数据方面却没有成功。任何建议将不胜感激。

事实上,石墨烯文档缺乏很多。看看这个复制数据的相当冗长但完整的示例:

import json
import graphene

# let's just prepare some data
SUCCESS = [{
    "id": "abc123",
    "goober": {
        "success": [
            {
                "id": "goober-type-1",
                "baz": "blahblahblah"
            },
            {
                "id": "goober-type-2",
                "baz": "blahblahblah"
            }
        ],
        "failed": [],
        "cancelled": []
    },
    "tronic": {
        "success": [
            {
                "id": "tronic-type-1",
                "baz": "blahblahblah"
            },
            {
                "id": "tronic-type-2",
                "baz": "blahblahblah"
            }
        ],
        "failed": [],
        "cancelled": []
    }
}]

FAILED = [{
    "id": "abc123",
    "goober": {
        "success": [],
        "failed": [
            {
                "id": "goober-type-3",
                "baz": "blahblahblah"
            }
        ],
        "cancelled": [
            {
                "id": "goober-type-4",
                "baz": "blahblahblah"
            }
        ]
    },
    "tronic": {
        "success": [],
        "failed": [
            {
                "id": "tronic-type-4",
                "baz": "blahblahblah"
            }
        ],
        "cancelled": [
            {
                "id": "tronic-type-3",
                "baz": "blahblahblah"
            }
        ]
    }
}]

class Goober(graphene.ObjectType):
    id = graphene.String()
    baz = graphene.String()

class Tronic(graphene.ObjectType):
    id = graphene.String()
    baz = graphene.String()

class GooberResult(graphene.ObjectType):
    success = graphene.List(Goober)
    failed = graphene.List(Goober)
    cancelled = graphene.List(Goober)

class TronicResult(graphene.ObjectType):
    success = graphene.List(Tronic)
    failed = graphene.List(Tronic)
    cancelled = graphene.List(Tronic)

class FooResult(graphene.ObjectType):
    id = graphene.String()
    goober = graphene.Field(GooberResult)
    tronic = graphene.Field(TronicResult)

class Foo(graphene.Mutation):
    success = graphene.List(FooResult)
    failed = graphene.List(FooResult)

    def mutate(self, info):
        # provide some data as a mutation result
        success = SUCCESS
        failed = FAILED
        return Foo(success=success, failed=failed)

class Mutation(graphene.ObjectType):
    foo = Foo.Field()

schema = graphene.Schema(mutation=Mutation)
result = schema.execute("""
mutation Foo {
    foo {
        success {
            id
            goober {
                success {
                    id
                    baz
                }
            }
        }
        failed {
            id
            tronic {
                cancelled {
                    id
                    baz
                }
            }
        }
    }
}
""")

print(json.dumps(result.data, indent=2))

当你运行这个脚本时,你会得到预期的结果:

{
  "foo": {
    "success": [
      {
        "id": "abc123",
        "goober": {
          "success": [
            {
              "id": "goober-type-1",
              "baz": "blahblahblah"
            },
            {
              "id": "goober-type-2",
              "baz": "blahblahblah"
            }
          ]
        }
      }
    ],
    "failed": [
      {
        "id": "abc123",
        "tronic": {
          "cancelled": [
            {
              "id": "tronic-type-3",
              "baz": "blahblahblah"
            }
          ]
        }
      }
    ]
  }
}

文档的起点可能是 relationship between ObjectTypes and Fields. Scalars act as Fields, however your defined ObjectTypes do not, that's why you need to wrap them in graphene.Field. Then just take a look at Mutations 一起使用。