Sequelize 模型联接

Sequelize Model Joins

提问人:mr.sean.r 提问时间:11/2/2023 最后编辑:mr.sean.r 更新时间:11/2/2023 访问量:38

问:

我正在使用 Node 和 Express、Sequelize 和 PostgreSql 构建一个 API。

我的员工将属于一个且只有一个部门。我有两张桌子,员工和部门。

我的项目中有以下两个模型,我使用 .关联和外键生成似乎按预期工作,当我浏览 PostgreSql 时,我看到了 fk 约束。sequelize-cli

employee model

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Employees extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  Employees.init({
    first_name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    last_name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    departmentId: {
      type: DataTypes.STRING,
      allowNull: false
    },
    createdBy: {
      type: DataTypes.STRING,
      allowNull: false
    },
    updatedBy: {
      type: DataTypes.STRING
    }
  }, {
    sequelize,
    modelName: 'Employees',
  });
 
  // UPDATED per suggestions
  Employees.associate = function(models) {
    Employees.belongsTo(models.Departments, {
      foreignKey: 'departmentId',
      as: "dept",
      onDelete: 'SET NULL',
    });
  };

  return Employees;
};

departments model

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Departments extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  }
  Departments.init({
    name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    description: {
      type: DataTypes.STRING
    },
    createdBy: {
      type: DataTypes.STRING,
      allowNull: false
    },
    updatedBy: {
      type: DataTypes.STRING
    }
  }, {
    sequelize,
    modelName: 'Departments',
  });

  // UPDATED per suggestions
  Departments.associate = function(models) {
    Departments.hasMany(models.Employees, {
      foreignKey: 'departmentId',
      as: "employees"
    });
  };

  return Departments;
};

employees migration

      departmentId: {
        type: Sequelize.INTEGER,
        onDelete: 'SET NULL',
        references: {
          model: {
            tableName: 'Departments',
          },
          key: 'id',
        },
      },

这一切似乎都运行良好,如果我尝试创建没有有效部门 ID 的员工,我会按预期收到约束错误。

当我找到所有员工使用时,我会收到如下所示的回复const employees = await this.db.employees.findAndCountAll();

{
    "count": 1,
    "rows":
    [
        {
            "id": 1,
            "first_name": "jon",
            "last_name": "doe",
            "departmentId": 1,
            "createdBy": "jane.dough"
        }
    ]
}

这一切都按预期工作。

顶级域名;

但是,当我尝试包含模型(将部门名称与部门 ID 连接起来)时Departmentsconst employees = await this.db.employees.findAndCountAll({include: [{model: this.db.departments,as: 'dept'}]});

I get the following association error.
"SequelizeEagerLoadingError: Departments is not associated to Employees!"

如何修复关联以将它们连接在一起。


更新: 在应用了 @nazrul-chowdhury 建议的更改后,我仍然看到错误。

我正在发布如何初始化数据库和模型的相关代码......我想我可能在我的过程中出了点问题。

employeeRepository.js

const { connect } = require('../config/db.config');


class EmployeeRepository {

    db = {};

    constructor() {
        this.db = connect();

    }

    async getEmployees() {
        try {
            const employees = await this.db.employees.findAndCountAll({include: [{model: this.db.departments,as: 'dept'}]});

db.config

const { Sequelize, Model, DataTypes } = require("sequelize");
// const logger = require('../logger/api.logger');

const connect = () => {

    const hostName = process.env.HOST;
    const userName = process.env.USER;
    const password = process.env.PASSWORD;
    const database = process.env.DB;
    const dialect = process.env.DIALECT;
    
    const sequelize = new Sequelize(database, userName, password, {
        host: hostName,
        dialect: dialect,
        operatorsAliases: 0,
        pool: {
            max: 10,
            min: 0,
            acquire: 20000,
            idle: 5000
        },
        logging: false
    });
    // turn off logging in production (log to console in all other environments)
    // logging: process.env.NODE_ENV === 'production' ? false : console.log

    const db = {};
    db.Sequelize = Sequelize;
    db.sequelize = sequelize;
    db.departments = require("../models/departments.model")(sequelize, DataTypes, Model);
    db.employees = require("../models/employees.model")(sequelize, DataTypes, Model);

    return db;

}

module.exports = {
    connect
}
node.js postgresql express sequelize.js sequelize-cli

评论


答:

0赞 Nazrul Chowdhury 11/2/2023 #1

您已经定义了员工和部门之间的一对一关联,但实际上您想要一种一对多关系,其中每个员工都属于一个部门,并且每个部门可以有多个员工。若要修复关联,应对模型进行一些更改。
在员工模型中,更改要使用的关联定义 belongsTo 而不是 hasOne,以指示员工属于某个部门。此外,还需要更新外键以匹配模型中的字段名称。

Employees.associate = function(models) {
  Employees.belongsTo(models.Departments, {
    foreignKey: 'departmentId', // Use the correct foreign key field
    as: 'dept',
    onDelete: 'SET NULL',
  });
};

在部门模型中,应删除 belongsTo 关联,因为部门不直接属于员工。相反,如果要检索与部门关联的员工,则可以在 Departments 模型中使用 hasMany 关联。

Departments.associate = function(models) {
  Departments.hasMany(models.Employees, {
    foreignKey: 'departmentId', // Use the correct foreign key field
    as: 'employees',
  });
};

评论

0赞 mr.sean.r 11/2/2023
感谢您的回答,我已经应用了您建议的更改,但仍然像以前一样看到关联错误。我添加了用于初始化数据库的代码以及用于获取所有员工的相关代码。