Prisma的update()方法如何仅更新模型中的部分指定字段?
1. 核心前提
首先明确:Prisma的update方法中,data对象里只需要传入你要更新的字段即可,未声明的字段会自动保留数据库原有值,不会做任何修改,完全符合你的需求。
2. 不推荐的写法
你给出的第一种示例写法有两个严重问题:
- JS对象语法不合法,不能直接在对象内用三元表达式控制键值对是否存在
- 如果条件不成立返回
null的话,会直接把对应字段的值覆盖为null,和你“保留原值”的需求完全相悖
3. 推荐的实现方案
你第二种手动构建对象的思路是正确的,但可以根据场景优化,避免写大量重复的if判断:
方案1:字段少、内部接口场景:直接清理空字段
// 先提取所有允许更新的字段,未传递的字段值为undefined const data = { firstname: req.firstname, lastname: req.lastname, address: req.address, email: req.email, phone: req.phone, mobile: req.mobile, age: req.age } // 清理所有值为undefined的键,避免传入无效字段 Object.keys(data).forEach(key => data[key] === undefined && delete data[key]) const updateUser = await prisma.user.update({ where: { email: 'viola@prisma.io' }, data })
方案2:字段多、对外接口场景:配合校验库过滤(生产环境最优)
如果你的项目已经接入了参数校验工具(比如Zod、Joi),直接定义允许更新的字段规则,校验后得到的对象就是干净的可更新对象,同时还能完成参数合法性校验:
以Zod为例:
import { z } from 'zod' // 定义允许更新的用户字段规则 const updateUserSchema = z.object({ firstname: z.string().min(1).optional(), lastname: z.string().min(1).optional(), address: z.string().optional(), email: z.string().email().optional(), phone: z.string().optional(), mobile: z.string().optional(), age: z.number().int().min(0).max(120).optional() }) // 校验请求参数,自动过滤掉规则外的非法字段 const validData = updateUserSchema.parse(req) const updateUser = await prisma.user.update({ where: { email: 'viola@prisma.io' }, data: validData })
4. 要不要逐一校验req的字段?
- 如果是内部接口、对调用方完全可控,不需要做严格校验的话,直接用方案1清理undefined字段即可
- 如果是对外接口、或者需要做参数合法性校验(比如邮箱格式、年龄范围),必须做校验,配合校验库的方案是最稳妥的,避免非法数据写入数据库。
内容的提问来源于stack exchange,提问作者skorpio
相关产品推荐
相关产品推荐

