提问人:mr.sean.r 提问时间:11/2/2023 最后编辑:mr.sean.r 更新时间:11/2/2023 访问量:38
Sequelize 模型联接
Sequelize Model Joins
问:
我正在使用 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 连接起来)时Departments
const 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
}
答:
您已经定义了员工和部门之间的一对一关联,但实际上您想要一种一对多关系,其中每个员工都属于一个部门,并且每个部门可以有多个员工。若要修复关联,应对模型进行一些更改。
在员工模型中,更改要使用的关联定义 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',
});
};
评论