4

PythonパッケージFlask、SQLAlchemy、Graphene、Graphene-SQLAlchemyを使用してGraphQL APIを構築しています。私はSQLAlchemy + Flask Tutorialに従いました。クエリとミューテーションを実行してレコードを作成できます。ここで、既存のレコードを更新する最良の方法を知りたいと思います。

これが私の現在のスクリプトschema.pyです:

from graphene_sqlalchemy import SQLAlchemyObjectType
from database.batch import BatchOwner as BatchOwnerModel
import api_utils  # Custom methods to create records in database
import graphene


class BatchOwner(SQLAlchemyObjectType):
    """Batch owners."""
    class Meta:
        model = BatchOwnerModel
        interfaces = (graphene.relay.Node,)


class CreateBatchOwner(graphene.Mutation):
    """Create batch owner."""
    class Arguments:
        name = graphene.String()

    # Class attributes
    ok = graphene.Boolean()
    batch_owner = graphene.Field(lambda: BatchOwner)

    def mutate(self, info, name):
        record = {'name': name}
        api_utils.create('BatchOwner', record) # Custom methods to create records in database
        batch_owner = BatchOwner(name=name)
        ok = True
        return CreateBatchOwner(batch_owner=batch_owner, ok=ok)


class Query(graphene.ObjectType):
    """Query endpoint for GraphQL API."""
    node = graphene.relay.Node.Field()
    batch_owner = graphene.relay.Node.Field(BatchOwner)
    batch_owners = SQLAlchemyConnectionField(BatchOwner)


class Mutation(graphene.ObjectType):
    """Mutation endpoint for GraphQL API."""
    create_batch_owner = CreateBatchOwner.Field()


schema = graphene.Schema(query=Query, mutation=Mutation)

備考:

  • 私のオブジェクトBatchOwnerには 2 つの属性 (ID、名前) しかありません
  • 名前を更新できるようにするにBatchOwnerは、更新メソッドの入力引数としてデータベース ID (リレー グローバル ID ではない) を指定する必要があると想定します。
  • しかしBatchOwner、クライアントから をクエリすると、Graphene は base64 でエンコードされたグローバル ID のみを返します (例:QmF0Y2hPd25lcjoxに対応するBatchOwner:1) 。

応答の例:

{
    "data": {
        "batchOwners": {
            "edges": [
                {
                    "node": {
                        "id": "QmF0Y2hPd25lcjox",
                        "name": "Alexis"
                    }
                }
            ]
        }
    }
}

現時点で考えている解決策は次のとおりです。

  • グローバル ID を引数として受け取る更新ミューテーションを作成します。
  • グローバル ID をデコードします (どのように?)
  • デコードされたグローバル ID から取得したデータベース ID を使用して、データベースを照会し、対応するレコードを更新します。

これを行うより良い方法はありますか?

4

1 に答える 1

6

メソッドを使用して解決策を見つけましたfrom_global_idここに文書化されています

from graphql_relay.node.node import from_global_id

次のクラスをschema.pyに追加しました。

class UpdateBatchOwner(graphene.Mutation):
    """Update batch owner."""
    class Arguments:
        id = graphene.String()
        name = graphene.String()

    # Class attributes
    ok = graphene.Boolean()
    batch_owner = graphene.Field(lambda: BatchOwner)

    def mutate(self, info, id, name):
        id = from_global_id(id)
        record = {'id': id[1], 'name': name}
        api_utils.update('BatchOwner', record)
        batch_owner = BatchOwner(id=id, name=name)
        ok = True
        return UpdateBatchOwner(batch_owner=batch_owner, ok=ok)

Mutation クラスを次のように更新しました。

class Mutation(graphene.ObjectType):
    """Mutation endpoint for GraphQL API."""
    create_batch_owner = CreateBatchOwner.Field()
    update_batch_owner = UpdateBatchOwner.Field()

これを行うためのより簡単な方法があるかどうか疑問に思っていますか?

于 2018-01-20T17:15:57.400 に答える