Sequelize中User与Gasto一对多关联及CASCADE删除失效求助
你的CASCADE删除不生效主要有三个核心问题:迁移文件未配置外键约束、模型关联关系错误、无关的onDelete配置放错位置,下面是具体修复步骤:
1. 修复Gasto迁移文件,添加外键约束和ON DELETE CASCADE
数据库层面的外键约束是CASCADE生效的基础,你的Gasto迁移里user_id字段只是普通整数,没有关联到users表的id,也没设置删除级联。修改后的迁移文件:
'use strict' /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, Sequelize) { await queryInterface.createTable('gastos', { id: { type: Sequelize.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true }, user_id: { type: Sequelize.INTEGER, allowNull: false, references: { model: 'users', key: 'id' }, onDelete: 'CASCADE', onUpdate: 'CASCADE' }, type: { type: Sequelize.STRING, allowNull: false }, value: { type: Sequelize.STRING, allowNull: false }, gasto_date: { type: Sequelize.STRING, allowNull: false } }) }, async down (queryInterface, Sequelize) { await queryInterface.dropTable('gastos') } }
同时删除User迁移里id字段上无效的onDelete: 'CASCADE'配置:
'use strict' /** @type {import('sequelize-cli').Migration} */ module.exports = { async up (queryInterface, Sequelize) { await queryInterface.createTable('users', { id: { type: Sequelize.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true }, username: { type: Sequelize.STRING, allowNull: false }, email: { type: Sequelize.STRING, allowNull: false }, role: { type: Sequelize.STRING, allowNull: false }, password: { type: Sequelize.STRING, allowNull: false } }) }, async down (queryInterface, Sequelize) { await queryInterface.dropTable('users') } }
2. 修复模型的关联关系
你在Gasto模型里用了Gasto.hasOne(User),这是错误的。一对多关系中,多方(Gasto)应该用belongsTo关联到一方(User),修改后的User模型:
import { DataTypes } from 'sequelize' import db from '.' import { Gasto } from './Gasto' export const User = db.define('User', { id: { type: DataTypes.INTEGER, autoIncrement: true, allowNull: false, primaryKey: true }, username: { type: DataTypes.STRING, allowNull: false }, email: { type: DataTypes.STRING, allowNull: false }, password: { type: DataTypes.STRING, allowNull: false }, role: { type: DataTypes.STRING, allowNull: false } }, { timestamps: false, tableName: 'users', underscored: true }) User.hasMany(Gasto, { foreignKey: 'userId', onDelete: 'CASCADE' }) // 替换原有的Gasto.hasOne(User),改为belongsTo Gasto.belongsTo(User, { foreignKey: 'userId' })
3. 重新执行迁移
修改完迁移文件后,执行以下命令更新数据库结构(开发环境可直接操作,生产环境需谨慎):
# 回滚旧迁移(如果已执行过) npx sequelize-cli db:migrate:undo # 重新执行所有迁移 npx sequelize-cli db:migrate
现在删除User时,关联的Gasto会被自动删除,无论是通过Sequelize的User.destroy()方法,还是直接在数据库中删除用户记录,都会触发CASCADE删除逻辑。
内容的提问来源于stack exchange,提问作者Igor Brizack
相关产品推荐
相关产品推荐

