我初次接触Sequelize.js和数据库,之前没有用过迁移,但我知道可以使用它们以非破坏性的方式对表结构进行更改。
然而,我不确定在哪里声明列选项(notNull、references、validate、ENUM值等)。
这些选项应该在模型文件还是迁移文件中声明?还是两者都要?
把选项添加到模型和迁移中不会导致重复代码吗?
(请注意,我说的是创建表格的初始迁移,而不是添加列等操作的迁移...)
谢谢您的帮助!
我初次接触Sequelize.js和数据库,之前没有用过迁移,但我知道可以使用它们以非破坏性的方式对表结构进行更改。
然而,我不确定在哪里声明列选项(notNull、references、validate、ENUM值等)。
这些选项应该在模型文件还是迁移文件中声明?还是两者都要?
把选项添加到模型和迁移中不会导致重复代码吗?
(请注意,我说的是创建表格的初始迁移,而不是添加列等操作的迁移...)
谢谢您的帮助!
我看到您有三种选择。前两个选项可能是边缘情况,但了解一下会有所帮助。
如果您想原型化一个项目并且不介意丢失数据,那么您可以无需关心迁移文件,只需按照您的模型同步数据库:
await sequelize.sync({ force: true });
它将在您的所有模型上执行:
DROP TABLE IF EXISTS "your_model" CASCADE;
CREATE TABLE IF NOT EXISTS "your_model" (...)
例如,此命令可以在应用程序启动时执行。
正如您所提到的,如果您不想添加列和其他内容,这可能是一个很好的选择。
现在,如果您不想丢失数据,您可以简单地使用同步方法而不使用强制选项:
await sequelize.sync({ });
它只会生成:
CREATE TABLE IF NOT EXISTS "your_model" (...)
# npx sequelize-cli init or create migrations and models folders
npx sequelize-cli model:generate --name User --attributes firstName:string,email:string
现在您将会有两个新文件:
// migrations/<date>-create-user.js
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
// I usually remove this and create the table only if not exists
return queryInterface.dropTable('Users');
}
};
// models/users.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: DataTypes.STRING,
email: DataTypes.STRING
}, {});
User.associate = function(models) {
// associations can be defined here
};
return User;
};
你可以将迁移和模型的代码进行重构,但这可能会很麻烦,因为某些迁移文件只会添加一个列,所以将它们全部合并到模型中可能会更加混乱。
你应该在两个地方做这件事情,因为随着时间的推移,你的模型和初始迁移将会不同。所以我认为你应该确定模型的最终结构,然后创建一个初始迁移。
约束是在SQL级别上定义和运行的,而验证是在应用程序级别上运行的。Sequelize支持在模型中具有验证和约束,但只能在迁移中定义约束。
我的意见是将所有约束放在迁移中,将验证放在模型中。这样,您就可以在向数据库发出查询之前运行验证,而在那里运行约束,从而实现某种关注点分离。您可以阅读更多关于Sequelize的验证和约束Validations and Constraints。