使用 Graphene 和 SQLAlchemy 通过 GraphQL API 更新记录
Update a record via a GraphQL API using Graphene and SQLAlchemy
我正在使用 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 只 returns 我是 base64 编码的全局 ID(例如:QmF0Y2hPd25lcjox
,对应于 BatchOwner:1
)
响应示例:
{
"data": {
"batchOwners": {
"edges": [
{
"node": {
"id": "QmF0Y2hPd25lcjox",
"name": "Alexis"
}
}
]
}
}
}
我目前想到的解决方案是:
- 创建一个以全局 Id 作为参数的更新突变
- 解码全局 Id(如何?)
- 使用从解码的全局Id中检索到的数据库Id查询数据库并更新相应的记录
有更好的方法吗?
我找到了使用方法 from_global_id
(documented here)
的解决方案
from graphql_relay.node.node import from_global_id
我将以下 class 添加到 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:
class Mutation(graphene.ObjectType):
"""Mutation endpoint for GraphQL API."""
create_batch_owner = CreateBatchOwner.Field()
update_batch_owner = UpdateBatchOwner.Field()
我想知道是否有更直接的方法来做到这一点?
我正在使用 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 只 returns 我是 base64 编码的全局 ID(例如:QmF0Y2hPd25lcjox
,对应于BatchOwner:1
)
响应示例:
{
"data": {
"batchOwners": {
"edges": [
{
"node": {
"id": "QmF0Y2hPd25lcjox",
"name": "Alexis"
}
}
]
}
}
}
我目前想到的解决方案是:
- 创建一个以全局 Id 作为参数的更新突变
- 解码全局 Id(如何?)
- 使用从解码的全局Id中检索到的数据库Id查询数据库并更新相应的记录
有更好的方法吗?
我找到了使用方法 from_global_id
(documented here)
from graphql_relay.node.node import from_global_id
我将以下 class 添加到 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:
class Mutation(graphene.ObjectType):
"""Mutation endpoint for GraphQL API."""
create_batch_owner = CreateBatchOwner.Field()
update_batch_owner = UpdateBatchOwner.Field()
我想知道是否有更直接的方法来做到这一点?