Prisma查询返回null?房屋删除接口校验失败求助
Prisma查询findFirst返回null的排查与解决
先看你的代码和问题:
import { prisma } from "../../../database/prismaClient" interface IDeleteHouseRequest { id: string tenantId: string } export class DeleteHouseUseCase { async execute({ id, tenantId }: IDeleteHouseRequest) { const findHouse = await prisma.house.findFirst({ where: { id: id, tenantId: tenantId }, }) if (!findHouse) { throw new Error("It was not possible to delete this house.") } const deletedHouse = await prisma.house.delete({ where: { id: id } }) return deletedHouse } }
问题描述:代码卡在该校验环节,已确认传入的id和tenantId参数正确,数据库中存在对应房屋数据,但findHouse查询结果为null,无法通过此校验。
下面是几个大概率的排查方向和解决方案:
1. 数据类型/格式不匹配
最常见的原因是传入参数的类型/格式和数据库存储的不一致:
- 比如数据库中
id是UUID类型,你传入的字符串大小写和库中不一致(部分数据库对UUID大小写敏感); - 或者
tenantId在Prisma Schema中定义为Int,但你传入的是字符串格式的数字; - 也可能是参数包含隐形空格,比如传入的
tenantId末尾多了空格。
解决:
- 打开
schema.prisma检查House模型的字段类型:model House { id String @id @default(uuid()) tenantId String // 确认这里的类型和传入参数一致 // 其他字段 } - 在查询前打印参数的原始值和类型,和数据库中存储的内容精确比对:
console.log("传入的id:", id, "类型:", typeof id) console.log("传入的tenantId:", tenantId, "类型:", typeof tenantId)
2. 全局中间件/软删除逻辑干扰
如果你的Prisma客户端初始化时加了全局中间件,比如软删除过滤,会导致查询自动加上额外条件,过滤掉你要找的数据:
// 示例:全局软删除中间件 prisma.$use(async (params, next) => { if (params.model === 'House') { params.args.where = { ...params.args.where, isDeleted: false } } return next(params) })
如果数据库中的目标数据isDeleted字段为true,findFirst就查不到。
解决:检查Prisma客户端的初始化代码,有没有类似的全局过滤逻辑;如果是软删除场景,查询时需要显式加上isDeleted: false(或对应状态)。
3. 数据库环境不匹配
你可能犯了低级错误:代码连接的数据库和你查看数据的数据库不是同一个(比如代码连测试库,你看的是生产库)。
解决:确认prisma/.env中的DATABASE_URL指向的数据库,和你用来验证数据存在的数据库是同一个;可以直接在数据库中执行原生SQL查询,验证参数是否能查到数据:
SELECT * FROM House WHERE id = '你的id' AND tenantId = '你的tenantId';
4. 优化方案:合并校验与删除操作
其实你不需要先查询再删除,Prisma的delete操作本身可以同时校验多个条件,而且更高效(减少一次数据库请求),还能避免查询后到删除前的数据变更问题:
import { prisma } from "../../../database/prismaClient" import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library' interface IDeleteHouseRequest { id: string tenantId: string } export class DeleteHouseUseCase { async execute({ id, tenantId }: IDeleteHouseRequest) { try { const deletedHouse = await prisma.house.delete({ where: { id: id, tenantId: tenantId // 同时校验id和tenantId } }) return deletedHouse } catch (error) { // 捕获Prisma的"找不到记录"错误 if (error instanceof PrismaClientKnownRequestError && error.code === 'P2025') { throw new Error("It was not possible to delete this house.") } // 抛出其他未知错误 throw error } } }
当找不到符合id和tenantId的记录时,Prisma会抛出P2025错误,直接捕获这个错误即可完成校验逻辑。
内容的提问来源于stack exchange,提问作者Hugo Vinicius
相关产品推荐
相关产品推荐

