Sequelize v6如何避免更新未变更字段?原v5特性失效求助
Sequelize v6 实现字段未变更时不执行更新的解决方法
在Sequelize v6中,instance.update()方法的默认行为改为无论字段是否变化都会执行SQL更新语句,替代v5的自动跳过逻辑可以用以下几种方式:
方法一:手动对比字段,仅更新有变化的内容
先获取实例当前数据,与待更新数据对比,筛选出差异字段后再执行更新:
const data = { userId: 1, login: 'admin', }; const { userId, ...userData } = data; const candidate = await findById(userId); // 筛选出与实例当前值不同的字段 const changedFields = {}; Object.keys(userData).forEach(key => { if (candidate.dataValues[key] !== userData[key]) { changedFields[key] = userData[key]; } }); // 仅当存在变化字段时执行更新,否则直接返回原实例 const record = Object.keys(changedFields).length ? await candidate.update(changedFields) : candidate; return record;
方法二:利用实例的变更追踪(set + save)
使用set()方法设置待更新数据,触发Sequelize的变更追踪,再通过getChangedData()获取变化字段,最后调用save()仅更新变化内容:
const data = { userId: 1, login: 'admin', }; const { userId, ...userData } = data; const candidate = await findById(userId); // 设置待更新数据,触发变更追踪 candidate.set(userData); // 获取实际发生变化的字段 const changedData = candidate.getChangedData(); // 有变化则保存,否则返回原实例 const record = Object.keys(changedData).length ? await candidate.save() : candidate; return record;
方法三:通过SQL条件控制更新范围
在update()的WHERE条件中添加字段不等于当前值的判断,仅当字段确实不同时才执行更新:
const { Op } = require('sequelize'); const data = { userId: 1, login: 'admin', }; const { userId, ...userData } = data; const candidate = await findById(userId); // 构建更新条件:仅当字段与实例当前值不同时才更新 const updateWhere = { id: userId, ...Object.fromEntries( Object.keys(userData).map(key => [key, { [Op.ne]: candidate.dataValues[key] }]) ) }; // 执行更新,获取受影响行数 const [affectedRows] = await YourModel.update(userData, { where: updateWhere }); // 受影响行数大于0说明有更新,重新查询实例;否则返回原实例 const record = affectedRows > 0 ? await findById(userId) : candidate; return record;
内容的提问来源于stack exchange,提问作者Данияр Булдаков
相关产品推荐
相关产品推荐

