我应该让 Sequelize 模型和迁移保持同步吗?
Posted
技术标签:
【中文标题】我应该让 Sequelize 模型和迁移保持同步吗?【英文标题】:Am i supposed to keep Sequelize models and migrations in sync? 【发布时间】:2020-09-07 05:08:26 【问题描述】:总的来说,我是 Sequelize.js 和数据库的新手,我以前没有使用过迁移,但我知道它们可以用于以非破坏性方式更改表结构。
但是我不确定在哪里声明列选项(notNull、引用、验证、ENUM 值等...)
我应该在模型文件或迁移文件中声明这些选项吗?或两者?
在模型和迁移中添加选项不会导致重复代码吗?
(请记住,我说的是为数据库创建表的初始迁移,而不是添加列和内容的迁移......)
任何帮助将不胜感激!
【问题讨论】:
相关:***.com/questions/21105748/… 【参考方案1】:我看到您可以采取三种选择。前两个选项可能是极端情况,但有助于理解。
破坏性选项
您想要为项目制作原型并且不介意丢失数据,那么您可能不关心迁移文件并根据您的模型同步您的数据库:
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" (...)
因此,您的表是根据您的模型创建的,您不必创建迁移文件。
但是,如果您想修改模型并且这是最常见的用例,新列将不会在表中动态生成,这就是您需要迁移脚本的原因。
灵活的选择
您必须同时定义迁移文件和模型。这就是cli 所做的。这是一个例子:
# 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;
;
您可以从迁移和模型中重构代码,但这会相当麻烦,因为某些迁移文件只会添加一列,因此将它们全部合并到模型中可能不太清楚。
【讨论】:
【参考方案2】:您应该在两者中都这样做,因为随着时间的推移,您的模型和初始迁移会彼此不同。所以我想你应该确定模型中的最终结构,然后创建初始迁移。
【讨论】:
【参考方案3】:约束在 SQL 级别定义和运行,而验证在应用程序级别运行。 Sequelize 支持对模型进行验证和约束,只能在迁移中定义约束。
我的意见是将所有约束放在迁移中,并将验证放在模型中。这样,您就有了某种关注点分离,因为在对数据库进行查询之前运行验证 - 运行约束。你可以阅读更多关于 Sequelize 的验证和约束Validations and Constraints
【讨论】:
以上是关于我应该让 Sequelize 模型和迁移保持同步吗?的主要内容,如果未能解决你的问题,请参考以下文章
即使 paranoid 设置为 true,Sequelize.js 仍会删除表行