在我第一次开始研究续集时,我只是不知道,只需要复制并粘贴代码,以便在两个模型之间建立关系。
我是否必须将外键同时插入到模型文件和迁移文件中,或仅用于迁移文件。
我知道迁移是包含更改数据库命令的文件。
所以我们必须手动将外键插入迁移文件,以便数据库可以创建它们。
在sequelize doc中,如果我们添加许多属于的关系,sequelize会自动添加外键。
所以我真的很困惑,是否必须添加它们。
在答案是五十五分之前,我问过一些问题。 有人说我们不必手动将外键添加到模型中,因为sequelize会自动添加它们。但有些人说我们必须手动将外键添加到模型中,因为我们必须在模型和迁移文件之间匹配(同步)列。
更糟糕的是,解释关于续集关系的文章彼此不同。那么,哪一个是对的?
我真的想得到明确的答案。
得到一些理由(如果我们必须在模型中添加外键)将非常感谢
不夸张,我对这个问题好奇了大约六个月。答案 0 :(得分:3)
创建迁移时,您还应该编写外键。也可以在模型中编写它,因此很容易处理查询。 我们可以通过示例看到它。考虑他们是两个表Item和Item_Types
1 Item_type有很多项目,
Item_type的迁移文件(migration_create_item_type.js)
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
return queryInterface.createTable('item_types', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
item_type: {
type: Sequelize.STRING
},
type_desc: {
type: Sequelize.STRING
},
createdAt: {
allowNull: true,
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
},
updatedAt: {
allowNull: true,
type: Sequelize.DATE,
defaultValue: Sequelize.NOW
}
});
},
down: function (queryInterface, Sequelize) {
return queryInterface.dropTable('item_types');
}
};
项目的迁移文件(migration_create_item.js)
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
return queryInterface.createTable('items', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
item_name: {
type: Sequelize.STRING
},
item_desc: {
type: Sequelize.STRING
},
item_type_id: {
type: Sequelize.INTEGER,
references: {
model: 'item_types',
key: 'id'
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: function (queryInterface, Sequelize) {
return queryInterface.dropTable('items');
}
};
请注意,始终创建父表1然后其他表,即创建所有没有外键的表,然后创建其他表
模型文件Item_type(item_type.js)
'use strict';
module.exports = function (sequelize, DataTypes) {
var item_type = sequelize.define('item_type', {
item_type: DataTypes.STRING,
type_desc: DataTypes.STRING
});
item_type.associate = function (models) {
item_type.hasMany(models.item, {foreignKey: 'item_type_id'});
};
return item_type;
};
模型归档项目(item.js)
'use strict';
var Logger = require('./../utils/logger');
var log = new Logger('item_type_factory');
module.exports = function (sequelize, DataTypes) {
var item = sequelize.define('item', {
item_name: DataTypes.STRING,
item_desc: DataTypes.STRING
});
item.associate = function (models) {
item.item_type = item.belongsTo(models.item_type, {foreignKey: 'id', target_key: 'item_type_id'});
item.order_details = item.hasMany(models.order_details);
item.user = item.belongsToMany(models.user, {through: 'supplier_items'})
};
item.addNewItem = function (data) {
return item.create(data, {include: [{association: item.item_type}]});
};
item.findAndCreate = function (data, item_name) {
return new Promise(function (resolve, reject) {
item.findOrCreate({
where: {'item_name': item_name}, defaults: data
}).spread(function (record_data, created) {
resolve(record_data);
}).catch(function (insert_error) {
reject(insert_error);
});
});
};
item.findAllItems = function () {
return item.findAll({
include: [{association: item.item_type}]
});
};
return item;
};
对于sequlize基础知识,您可以参考以下文章, Getting started with Sequelize仅限基础知识。
答案 1 :(得分:2)
我们有两种选择。使用sync
进行迁移或续作。始终更喜欢sync
以上的迁移。迁移功能更强大,您可以使用它进行撤消,重做等等。 sync
未反映表格更改。例如,您定义某个模型说User
并忘记添加gender
。现在,如果您要使用Sequelize添加此列,则必须使用force:true
,这会丢弃生产中不可取的所有User
数据。
从软件设计原则来看,无论应用程序逻辑(Sequelize)是否实现相同的逻辑,您的数据库约束和验证都应该始终存在。例如,如果您没有正确的约束,新开发人员可以编写原始查询,并且可能会弄乱您的整个数据库。
但是我们也希望使用sequelize来对所有关联进行正确的查询。如果它知道数据库中存在哪些关联以及什么应该是外键,那么sequelize的唯一方法就可以做到这一点。
因此,应该在迁移和续集级别定义外键约束。
如上图所示,约束是在我的数据库模式中定义的。
module.exports = (sequelize, DataTypes) => {
const Designation = sequelize.define('designation', {
doctorId: {
type: DataTypes.STRING,
allowNull: false,
field: 'doctor_id',
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
}, {});
Designation.associate = (models) => {
models.designation.belongsTo(models.doctor, {
onDelete: 'cascade',
});
};