背景
我正在使用SequelizeJS构建一个项目,这是一个流行的NodeJS ORM。在设计架构时,似乎有两种策略:
我的理解是#1对于快速原型设计更好,但对于预计会随着时间的推移而发展并且生产数据需要能够在迁移中存活的项目而言,#2是最佳实践。
这个问题与战术#2有关。
问题
我的表有必须通过外键反映的关系。
如何通过Sequelize QueryInterface创建具有外键关系的表?
Sequelize需要哪些列和帮助程序表?例如,似乎需要特定的列,例如createdAt或updatedAt。
答案 0 :(得分:25)
如何通过Sequelize QueryInterface创建具有外键关系的表?
.createTable()
方法接受列的字典。您可以在documentation for .define()
中查看有效属性列表,特别是通过查看params表中的[attributes.column.*]
行。
要创建具有外键关系的属性,请使用"引用"和" referencesKey"字段:
例如,以下内容将创建一个users
表,以及一个引用users表的user_emails
表。
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
}
}).then(function() {
queryInterface.createTable('user_emails', {
userId: {
type: Sequelize.INTEGER,
references: { model: 'users', key: 'id' }
}
})
});
sequelize需要哪些列和帮助程序表?例如,似乎需要特定的列,例如createdAt或updatedAt。
标准模型似乎希望每个表都有id
,updatedAt
和createdAt
列。
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
createdAt: {
type: Sequelize.DATE
},
updatedAt: {
type: Sequelize.DATE
}
}
如果您在模型上设置paranoid
to true
,则还需要deletedAt
时间戳。
答案 1 :(得分:5)
我想提供另一个更多手动替代,因为在使用手动迁移和queryInterface时,我遇到了以下问题:我在迁移文件夹中有2个文件,如此
migrations/create-project.js
migrations/create-projectType.js
因为project
列projectTypeId
引用了projectType
,由于文件的顺序而没有创建,因此导致错误。
我通过在创建两个表之后添加外键约束来解决它。就我而言,我决定在create-projectType.js
内写一下:
queryInterface.createTable('project_type', {
// table attributes ...
})
.then(() => queryInterface.addConstraint('project', ['projectTypeId'], {
type: 'FOREIGN KEY',
name: 'FK_projectType_project', // useful if using queryInterface.removeConstraint
references: {
table: 'project_type',
field: 'id',
},
onDelete: 'no action',
onUpdate: 'no action',
}))
答案 2 :(得分:5)
这是为了创建用于添加列的迁移文件。
在这里,我想在用户表中添加列 area_id 。运行命令:
sequelize migration:create --name add-area_id-in-users
执行后,将在迁移文件夹中创建一个迁移文件 timestamp-add-region_id-in-users 。
在创建的迁移文件中粘贴以下代码:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.addColumn('users', 'region_id',
{
type: Sequelize.UUID,
references: {
model: 'regions',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
defaultValue: null, after: 'can_maintain_system'
}),
]);
},
down: (queryInterface, Sequelize) => {
return Promise.all([
queryInterface.removeColumn('users', 'region_id'),
]);
}
};
在users表中,我将创建一个名为region_id的列以及类型和关系/外键/引用。就是这样。
答案 3 :(得分:-1)
第一个解决方案如下,第二个问题:您无需明确提及createdAt
和updatedAt
,因为它们是由Sequelize为您生成的。
解决方案是:
queryInterface.createTable('Images', {
//...
}).then(
return queryInterface.addConstraint('Images', ['postId'], {
type: 'foreign key',
name: 'custom_fkey_images',
references: { //Required field
table: 'Posts',
field: 'id'
},
onDelete: 'cascade',
onUpdate: 'cascade'
})
)