如何在 Sequelize 中正确设置自定义“通过”表?

Posted

技术标签:

【中文标题】如何在 Sequelize 中正确设置自定义“通过”表?【英文标题】:How do I correctly set up a custom 'through' table in Sequelize? 【发布时间】:2019-09-20 11:12:50 【问题描述】:

我正在尝试在使用 Sequelize 的项目中设置自定义直通表。我有一个计划表和一个任务表。现在,我希望实现一个将两者关联起来的表,但我想添加一个自定义列“完成”。运行sync() 时,似乎所有表都设置正确。这是它为设置 PlanningTask 表而运行的查询:

CREATE TABLE IF NOT EXISTS `PlanningTask` 
(`done` TINYINT(1) NOT NULL, `PlanningId` INTEGER(11) , `TaskId` INTEGER(11) ,
 PRIMARY KEY (`PlanningId`, `TaskId`), 
FOREIGN KEY (`PlanningId`) REFERENCES `Plannings` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
FOREIGN KEY (`TaskId`) REFERENCES `Tasks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) 
ENGINE=InnoDB;

以下是当前型号: 任务.js

module.exports = (sequelize, DataTypes) => 
    const Task = sequelize.define('Task', 
        id: 
            type: DataTypes.INTEGER(11),
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        ,
        type: 
            type: DataTypes.STRING,
            allowNull: false
        ,
        description: 
            type: DataTypes.STRING,
            allowNull: false
        ,
    )
    Task.associate = function(models) 
        Task.belongsToMany(models.Planning, 
            through: 'PlanningTask'
        )
    
    // Methods
    return Task

planning.js

module.exports = (sequelize, DataTypes) => 
  const Planning = sequelize.define('Planning', 
    id: 
      type: DataTypes.INTEGER(11),
      allowNull: false,
      autoIncrement: true,
      primaryKey: true
    ,
    title: 
      type: DataTypes.STRING,
      allowNull: false
    
    )
    Planning.associate = function (models) 
        Planning.belongsTo(models.User, 
            foreignKey: 'owner'
        )
        Planning.belongsToMany(models.Task, 
            through: 'PlanningTask'
        )
  
  // Methods
  return Planning

planningtask.js

module.exports = (sequelize, DataTypes) => 
  const PlanningTask = sequelize.define('PlanningTask', 
    done: 
      type: DataTypes.BOOLEAN,
      allowNull: false
    
    , 
        timestamps: false,
        freezeTableName: true       
    )
    PlanningTask.associate = function (models) 
        PlanningTask.belongsTo(models.Planning)
        PlanningTask.belongsTo(models.Task)
  
  // Methods
  return PlanningTask

所有模型都使用以下 index.js 文件加载:

const fs = require('fs')
const path = require('path')
const Sequelize = require('sequelize')
const config = require('../config/config')
const db = 

const sequelize = new Sequelize(
  config.db.database,
  config.db.user,
  config.db.password,
  config.db.options
)

fs
  .readdirSync(__dirname)
  .filter((file) =>
    file !== 'index.js'
  )
  .forEach((file) => 
    const model = sequelize.import(path.join(__dirname, file))
    db[model.name] = model
  )

Object.keys(db).forEach(function (modelName) 
  if ('associate' in db[modelName]) 
    db[modelName].associate(db)
  
)

db.sequelize = sequelize
db.Sequelize = Sequelize

module.exports = db

我想知道订单是否可能存在问题(关联注册在订单规划、规划任务、任务中)但是当我更改订单时它仍然不起作用。该表已正确创建,但是当我尝试使用 Planning.add([task]) 输入任务时,它会运行以下查询:

SELECT `done`, `PlanningId`, `TaskId`
FROM `PlanningTask` AS `PlanningTask`
WHERE `PlanningTask`.`PlanningId` = 1 AND `PlanningTask`.`TaskId` IN (1);

因此,对于 PlanningId,它会尝试“= 1”,这是正确的,但对于 TaskId,它使用“IN (1)”,这是不正确的。在这种情况下,1 是正确的任务 ID。

是我在关联中做错了什么,还是我尝试输入任务的方式有问题?

【问题讨论】:

【参考方案1】:

我的错。 “完成”列仍设置为必需,在我的测试中我没有为它发送值,其余的工作正常。

【讨论】:

以上是关于如何在 Sequelize 中正确设置自定义“通过”表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在关联表Sequelize js中获取自定义字段

Sequelize 多对多自引用

如何在 Sequelize 中的导入模型中创建自定义方法或函数

如何在 Node.JS 中向 sequelize.js 添加自定义函数?

Sequelize如何添加自定义排序功能?

sequelize 播种机上的自定义查询