我应该保持Sequelize模型和迁移同步吗?

6

我初次接触Sequelize.js和数据库,之前没有用过迁移,但我知道可以使用它们以非破坏性的方式对表结构进行更改。

然而,我不确定在哪里声明列选项(notNull、references、validate、ENUM值等)。

这些选项应该在模型文件还是迁移文件中声明?还是两者都要?

把选项添加到模型和迁移中不会导致重复代码吗?

(请注意,我说的是创建表格的初始迁移,而不是添加列等操作的迁移...)

谢谢您的帮助!


2
相关链接:https://dev59.com/gGEi5IYBdhLWcg3wndZw?rq=1 - Gjergj Kadriu
3个回答

6

我看到您有三种选择。前两个选项可能是边缘情况,但了解一下会有所帮助。

破坏性的选择

如果您想原型化一个项目并且不介意丢失数据,那么您可以无需关心迁移文件,只需按照您的模型同步数据库:

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

你应该在两个地方做这件事情,因为随着时间的推移,你的模型和初始迁移将会不同。所以我认为你应该确定模型的最终结构,然后创建一个初始迁移。


1

约束是在SQL级别上定义和运行的,而验证是在应用程序级别上运行的。Sequelize支持在模型中具有验证和约束,但只能在迁移中定义约束。

我的意见是将所有约束放在迁移中,将验证放在模型中。这样,您就可以在向数据库发出查询之前运行验证,而在那里运行约束,从而实现某种关注点分离。您可以阅读更多关于Sequelize的验证和约束Validations and Constraints


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接