Node.js Sequelize 通过questionId级联删除父表及关联子表数据求助
解决方案
梳理你现有代码的4个核心问题:
- 控制器导入模型错误,将Question模型错误导入为Option模型
- 删除条件写错:Question表的主键字段为
id,你误写为questionId - 未显式声明Sequelize层面的模型关联,仅在外键定义中加
onDelete: CASCADE无法生效 - 删除结果判断逻辑错误:
destroy方法返回的是被删除的行数(数字类型),你错误当成数组取下标判断
步骤1:补全模型关联定义
在所有模型定义完成后,统一添加关联关系,示例代码如下:
// 请将这段代码放在三个模型都导入完成的位置,比如模型入口文件中 import Question from './question.js' import Option from './option.js' import Answer from './answer.js' // Question和Option关联 Question.hasMany(Option, { foreignKey: 'questionId', onDelete: 'CASCADE' }) Option.belongsTo(Question, { foreignKey: 'questionId' }) // Question和Answer关联 Question.hasMany(Answer, { foreignKey: 'questionId', onDelete: 'CASCADE' }) Answer.belongsTo(Question, { foreignKey: 'questionId' }) // 可选:Option和Answer关联,实现删除选项时同步删除关联答案 Option.hasMany(Answer, { foreignKey: 'optionId', onDelete: 'CASCADE' }) Answer.belongsTo(Option, { foreignKey: 'optionId' })
步骤2:修复控制器代码
修正导入路径、删除条件、返回状态码和结果判断逻辑:
//models 修正为指向Question模型的正确路径 import Question from "../../../models/model-tesportal/question.js"; //helpers import { validationErrorHandler } from "../../../helpers/validation-error-handler.js"; export const deleteTestSeries = async (req, res, next) => { validationErrorHandler(req, next); const questionId = req.params.questionId; try { const result = await Question.destroy({ where: { id: questionId, }, }); if (result === 0) { const error = new Error("Question not found"); error.statusCode = 404; return next(error); } res.status(200).json({ message: "Question Deleted successfully", }); } catch (err) { if (!err.statusCode) { err.statusCode = 500; } next(err); } };
步骤3:数据库外键约束检查
如果你的表是之前已经创建完成的,需要更新外键约束:
- 开发环境可直接执行
sequelize.sync({ alter: true })同步表结构,不会清空现有数据,仅修改表结构 - 生产环境建议手动执行SQL修改外键,确保
options、answers表的questionId外键开启ON DELETE CASCADE属性
内容的提问来源于stack exchange,提问作者Er Dilshad Azam
相关产品推荐
相关产品推荐

