Sequelize使用findOrCreate后无法获取创建条目ID的问题求助
解决Sequelize findOrCreate获取新建标签ID的问题
我完全懂你遇到的坑——findOrCreate的返回逻辑和create不一样,直接拿result.id肯定会返回null,因为它返回的是一个包含标签实例对象和是否创建成功的布尔值的数组,不是单个实例对象。咱们一步步把问题理顺:
第一步:修复标签控制器的方法
你之前修改的控制器里用了spread解构,但没把处理后的实例返回出去,导致后续的then链拿不到有效数据。调整成这样:
module.exports = { findOrCreate(req, res, tag) { return Tags.findOrCreate({ where: { name: tag }, defaults: { name: tag } }) .spread((tagInstance, created) => { // 可选:根据created状态做日志或其他操作 console.log(`标签${created ? "已创建" : "已存在"}:`, tagInstance.get({ plain: true })); // 核心:把标签实例返回给下一个then回调 return tagInstance; }); } };
第二步:修正app.js里的调用逻辑
把原来调用tagsController.create改成上面的findOrCreate方法,同时梳理异步流程(你用了async.forEachOf,要确保Promise链正确传递):
function(sales, callback) { if(req.body.tags) { tagsArray = req.body.tags.split(','); // 不用把数组转成对象,直接遍历更简洁 callback(null, async.forEachOf(tagsArray, (tagName, key, callback) => { tagsController.findOrCreate(req, res, tagName) .then(tagInstance => { // 现在tagInstance是完整的标签实例,能直接拿到id return tagSpottingController.create(req, res, tagInstance.id, idCreation); }) .then(() => callback()) // 通知forEachOf当前迭代完成 .catch(err => callback(err)); // 捕获错误,避免流程卡住 })); } else { callback(null); // 没有标签时直接结束流程 } }
为什么之前的代码会出错?
findOrCreate默认返回[实例对象, 创建状态]的数组,不是单个实例,所以直接result.id会取不到值;- 你修改后的控制器里
spread块只做了console.log,没有返回实例,导致后续then拿到的是undefined; - 原来用
reduce把数组转成对象完全没必要,直接遍历原数组更清晰。
额外小技巧(Sequelize v6+适用)
如果你的Sequelize版本是v6及以上,也可以用数组解构代替spread,写法更直观:
return Tags.findOrCreate({ where: { name: tag }, defaults: { name: tag } }) .then(([tagInstance, created]) => { return tagInstance; });
这样不管是新建的标签还是已存在的标签,你都能稳稳拿到它的id了。
内容的提问来源于stack exchange,提问作者Kim Rose
相关产品推荐
相关产品推荐

