如何在Hasura GraphQL中为Mutation条件性绑定变量实现Upsert
问题
想要创建一个Upsert Mutation,要求id由数据库生成:当$id变量已设置时执行更新操作,否则执行创建操作。尝试了以下代码:
mutation upsert ( $id: uuid $name: String ) { insert_data_one( object: { id: $id name: $name } on_conflict: { constraint: data_pkey update_columns: [name ] } ) { id name } }
但收到id格式错误的报错,错误信息如下:
{ "errors": [ { "extensions": { "path": "$.selectionSet.insert_data_one.args.object.id", "code": "validation-failed" }, "message": "unexpected null value for type \"uuid\"" } ] }
解决方法
之所以报错,是因为当$id为null时,直接把id: $id传入object会触发类型校验失败——数据库的uuid主键字段不接受null值。
要实现「有id就更新,没id就插入」的逻辑,核心是只在$id存在时才传入id字段,否则数据库会自动生成主键。可以用GraphQL的条件片段语法来动态构造参数:
修正后的代码
mutation upsert ( $id: uuid $name: String! ) { insert_data_one( object: { # $id不为空时才传入id,否则跳过该字段 ...($id != null ? { id: $id } : {}) name: $name } on_conflict: { constraint: data_pkey # 只有$id存在时才配置更新字段,插入时冲突逻辑不会触发 ...($id != null ? { update_columns: [name] } : {}) } ) { id name } }
额外说明
- 把
$name设为String!是为了避免插入时name为空的情况,业务允许的话可以去掉!。 - 这个写法利用了GraphQL的内联条件扩展语法,动态控制是否传入id字段和更新配置,完美匹配你要的upsert逻辑。
- 如果用的是Hasura这类工具,也可以用其提供的
upsert简化写法,但核心思路都是「不传递null的id字段」。
内容的提问来源于stack exchange,提问作者itaied
相关产品推荐
相关产品推荐

