You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:00:58