sequelize 中的参考字段是什么?
What is the references field for in sequelize?
我有一个用户 table,它有角色 table 的外键列。
我在 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
我应该在 playground 中通过以下查询取回用户角色列表:
{users
{roles
{Name, Id}
}
}
相反,我得到了
roles is not associated to user!
后来想通了,需要做一个联想:
user.associate = models => {
user.hasMany(models.roles, {
foreignKey: 'Id',
sourceKey: 'RoleId',
onDelete: 'cascade',
});
};
然后就成功了。
我还是不明白这在用户模型中的作用是什么?:
references: {
model: 'roles',
key: 'Id',
},
我认为这是我的 "association" 和 table 角色,但如果我没有明确添加关联,这根本没有任何作用。有人可以解释一下 references
字段的含义吗?
references 用于描述迁移中的模型以及使用同步功能自动创建表。要操作数据(不是结构),您可以使用 user.hasMany
等关联
给出的答案是正确的,但后来我意识到这个问题的原因是我假设我可以通过代码创建关联,这样我就不必默认手动修改每个模型。
对于那些想做同样事情的人,我找到了一个解决方案 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');
我有一个用户 table,它有角色 table 的外键列。
我在 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
我应该在 playground 中通过以下查询取回用户角色列表:
{users
{roles
{Name, Id}
}
}
相反,我得到了
roles is not associated to user!
后来想通了,需要做一个联想:
user.associate = models => {
user.hasMany(models.roles, {
foreignKey: 'Id',
sourceKey: 'RoleId',
onDelete: 'cascade',
});
};
然后就成功了。
我还是不明白这在用户模型中的作用是什么?:
references: {
model: 'roles',
key: 'Id',
},
我认为这是我的 "association" 和 table 角色,但如果我没有明确添加关联,这根本没有任何作用。有人可以解释一下 references
字段的含义吗?
references 用于描述迁移中的模型以及使用同步功能自动创建表。要操作数据(不是结构),您可以使用 user.hasMany
等关联给出的答案是正确的,但后来我意识到这个问题的原因是我假设我可以通过代码创建关联,这样我就不必默认手动修改每个模型。
对于那些想做同样事情的人,我找到了一个解决方案 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');