sequelize 中的引用字段是啥?
Posted
技术标签:
【中文标题】sequelize 中的引用字段是啥?【英文标题】:What is the references field for in sequelize?sequelize 中的引用字段是什么? 【发布时间】:2020-07-22 09:24:29 【问题描述】:我有一个用户表,其中包含角色表的外键列。
我在 mysql 中定义了所有关系并使用sequelize-auto
生成了我的模型。
为用户生成的模型是这样的:
const user = sequelize.define('user',
Id:
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true,
,
Email:
type: DataTypes.STRING(45),
allowNull: false,
unique: true,
,
RoleId:
type: DataTypes.INTEGER(11),
allowNull: false,
references:
model: 'roles',
key: 'Id',
,
,
);
我认为我的引用已设置,因此当我在解析器中执行以下操作时:
users: async () =>
const users = await db.user.findAll(
include: [
model: db.roles,
,
],
);
return users
我应该在操场上使用以下查询返回用户角色列表:
users
roles
Name, Id
我得到了
角色未与用户关联!
后来我发现我需要建立一个关联:
user.associate = models =>
user.hasMany(models.roles,
foreignKey: 'Id',
sourceKey: 'RoleId',
onDelete: 'cascade',
);
;
然后它起作用了。
我还是不明白,这在用户模型中有什么用?:
references:
model: 'roles',
key: 'Id',
,
我认为这是我与角色表的“关联”,但没有我明确添加关联,这根本没有任何作用。有人可以解释references
字段的含义吗?
【问题讨论】:
【参考方案1】:给定的答案是正确的,但后来我意识到这个问题的原因是我认为我可以通过代码创建关联,这样我就不必默认手动修改每个模型。
对于那些想要做同样事情的人,我找到了一个解决方案 here。
基本上是:
1) 在您的模型文件夹中创建一个 index.js 文件并添加以下代码
import Sequelize from 'sequelize';
const fs = require('fs');
const path = require('path');
const basename = path.basename(__filename);
const db = ;
// @ts-ignore
const sequelize = new Sequelize('dbname', 'dbUser', 'password',
host: '127.0.0.1',
port: 'PORT',
dialect: 'mysql',
define:
freezeTableName: true,
timestamps: false,
,
pool:
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
,
// <http://docs.sequelizejs.com/manual/tutorial/querying.html#operators>
operatorsAliases: false,
);
const tableModel = ;
fs.readdirSync(__dirname)
.filter(file => file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js')
.forEach(file =>
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
tableModel[model.name] = model;
);
Object.getOwnPropertyNames(db).forEach(modelName =>
const currentModel = db[modelName];
Object.getOwnPropertyNames(currentModel.rawAttributes).forEach(attributeName =>
if (
Object.prototype.hasOwnProperty.call(
currentModel.rawAttributes[attributeName],
'references'
) &&
Object.prototype.hasOwnProperty.call(
currentModel.rawAttributes[attributeName].references,
'model'
) &&
Object.prototype.hasOwnProperty.call(
currentModel.rawAttributes[attributeName].references,
'key'
)
)
if (
!(
currentModel.rawAttributes[attributeName].references.model &&
currentModel.rawAttributes[attributeName].references.key
)
)
console.log(
`*SKIPPED* $modelName $attributeName references a model $currentModel.rawAttributes[attributeName].references.model with key $currentModel.rawAttributes[attributeName].references.key`
);
return;
console.log(
`$modelName $attributeName references a model $currentModel.rawAttributes[attributeName].references.model with key $currentModel.rawAttributes[attributeName].references.key`
);
const referencedTable =
tableModel[currentModel.rawAttributes[attributeName].references.model];
currentModel.belongsTo(referencedTable, foreignKey: attributeName );
referencedTable.hasMany(currentModel, foreignKey: attributeName );
);
);
// @ts-ignore
db.sequelize = sequelize;
// @ts-ignore
db.Sequelize = Sequelize;
// eslint-disable-next-line eol-last
module.exports = db;
2) 在您的解析器内部只需参考上述内容:
const db = require('../assets/models/index');
【讨论】:
【参考方案2】:references 用于描述迁移中的模型以及使用同步功能自动创建表。要操作数据(不是结构),您可以使用 user.hasMany
之类的关联【讨论】:
所以它是一个描述,但如果我只专注于在我的后端环境中实用并在 mysql 工作台中创建所有关系,那么这个字段对我来说没用吗?但是,如果我想从我的后端创建表到我的 mysql 环境,那么这有用吗? 如果您将使用迁移来创建和修改数据库结构,那么您根本不需要模型中的“引用”。所有这些引用都将在迁移中帮助后续 CLI 创建外键。sequelize-auto
的当前版本 0.7.5 自动生成关联。以上是关于sequelize 中的引用字段是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Sequelize.hasMany/belongsTo中的foreignKey是啥意思?