一对多关系中更新/新增子实体时如何自动更新父实体updatedTime字段?
可选解决方案(比Prisma中间件更轻量化)
下面按实现成本从低到高排序:
1. 手动显式更新updatedTime(零额外配置,最简便)
你只需要在父实体的update查询参数中,主动给updatedTime赋值为当前时间即可,不需要修改Schema、不需要加任何额外逻辑。
修改后的示例代码如下:
prisma.parent.update({ where: { uuid: someParent.uuid, }, data: { // 新增这一行手动触发更新 updatedTime: new Date(), children: { create: { name: "Joe", age: 30 } } } });
适用场景:仅少数几个业务接口需要做关联更新的情况,没有额外维护成本。
2. 数据库触发器(数据库层兜底,无业务侵入)
因为你用的是PostgreSQL,可以直接在数据库层面创建触发器,只要child表的数据发生和parent_uuid相关的增删改,就自动更新对应父实体的updated_time字段,完全不需要修改业务代码。
触发器创建SQL示例:
-- 第一步:创建触发器函数 CREATE OR REPLACE FUNCTION update_parent_updated_time() RETURNS TRIGGER AS $$ BEGIN -- 插入/更新子实体时更新对应父级 IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') AND NEW.parent_uuid IS NOT NULL THEN UPDATE parent SET updated_time = NOW() WHERE uuid = NEW.parent_uuid; END IF; -- 删除子实体时更新原对应父级 IF TG_OP = 'DELETE' AND OLD.parent_uuid IS NOT NULL THEN UPDATE parent SET updated_time = NOW() WHERE uuid = OLD.parent_uuid; END IF; RETURN NULL; END; $$ LANGUAGE plpgsql; -- 第二步:绑定触发器到child表的增删改事件 CREATE TRIGGER trigger_child_change_update_parent AFTER INSERT OR UPDATE OF parent_uuid OR DELETE ON child FOR EACH ROW EXECUTE FUNCTION update_parent_updated_time();
适用场景:所有子实体变动都需要更新父级时间的场景,不会因为业务代码漏写逻辑导致时间不更新,可靠性最高。
3. Prisma扩展(比传统中间件更轻量化的应用层方案)
如果你不想在数据库加触发器,又不想每次手动写更新时间,可以用Prisma 4.16及以上版本支持的扩展功能,针对parent.update方法做统一封装,比传统Prisma中间件写法更简洁,性能也更好。
示例代码:
const prisma = new PrismaClient().$extends({ query: { parent: { update({ args, query }) { // 只要更新请求里包含children的操作,就自动加updatedTime更新 if (args.data.children) { args.data.updatedTime = new Date(); } return query(args); }, }, }, });
适用场景:需要在应用层统一控制逻辑,且不想在数据库加额外对象的场景。
内容的提问来源于stack exchange,提问作者kwhk
相关产品推荐
相关产品推荐

