使用Graphene和SQLAlchemy

时间:2018-01-20 16:44:35

标签: python sqlalchemy flask-sqlalchemy graphql graphene-python

我正在使用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,name)
  • 为了能够更新BatchOwner名称,我假设我需要提供数据库Id(不是中继全局Id)作为某种更新方法的输入参数
  • 但是当我从我的客户端查询BatchOwner时,Graphene只返回我编码为base64的全局Id(例如:QmF0Y2hPd25lcjox,对应于BatchOwner:1

回复示例:

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

我现在想到的解决方案是:

  • 创建一个以全局Id作为参数的更新变异
  • 解码全局ID(如何?)
  • 使用从已解码的全局ID中检索到的数据库ID来查询数据库并更新相应的记录

有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

我找到了使用方法from_global_iddocumented here

的解决方案
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()

我想知道是否有更直接的方法来做到这一点?