了解Sequelize数据库迁移和种子

pky*_*eck 8 database database-migration node.js sequelize.js

我正在努力将Sequelize的迁移以及它们如何与种子一起工作(或者一般来说是迁移和种子)。
我设置了一切以使迁移正常进行。

首先,让我们创建一个users表:

// migrations/01-create-users.js
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable("Users", {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      email: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
      },
      updatedAt: {
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable("Users");
  }
};
Run Code Online (Sandbox Code Playgroud)

精细。如果要播种(管理员)用户,可以按以下步骤进行操作:

// seeders/01-demo-user.js
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.bulkInsert(
      "Users",
      [
        {
          email: "demo@demo.com"
        }
      ],
      {}
    );
  },

  down: (queryInterface, Sequelize) => {
    return queryInterface.bulkDelete("Users", null, {});
  }
};
Run Code Online (Sandbox Code Playgroud)

然后使魔术发生,我这样做:

$ sequelize db:migrate
Run Code Online (Sandbox Code Playgroud)

这将users在数据库中创建表。运行迁移后,下一步是播种,因此:

$ sequelize db:seed:all
Run Code Online (Sandbox Code Playgroud)

塔塔阿,现在我在users数据库中有一个用户。大。

但是现在我想添加firstnameusers表中,所以我必须添加另一个迁移:

// migrations/02-alter-users.js
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.addColumn("Users", "firstname", {
      type: Sequelize.STRING
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.removeColumn("Users", "firstname");
  }
};
Run Code Online (Sandbox Code Playgroud)

再次运行迁移将仅运行第二个迁移,因为第二个迁移已保存在数据库中,而第一个已经执行。但是默认情况下,sequelize重新运行所有播种机。那么,我应该调整seeders/01-demo-user.js还是更改默认行为,并将种子存储在数据库中并创建一个仅更新种子的新种子firstname

如果firstname不可能的话null,那么先运行迁移,然后运行旧版本的迁移seeders/01-demo-user.js将引发错误,因为firstname不可能null

重新运行播种机会导致另一个问题:demo@demo.com电子邮件已经有一个用户。再次运行它将复制用户。还是我必须在播种机中检查类似的事情?

以前,我只是在迁移中添加了用户帐户,因此可以确定何时将其添加到数据库中以及何时必须对其进行更新。但是有人告诉我我做错了所有事情,我必须使用播种机来完成这样的任务。

任何帮助/见解非常感谢。

Ann*_*hko 6

在我看来,播种机是一种只能运行一次的东西,而迁移是您不断地将一层一层地添加到数据库结构中的东西。

我会使用播种机来填充一些最有可能不会改变的查找或其他数据,或测试数据。在sequelize 文档中说,“种子文件是数据中的一些更改,可用于用示例数据或测试数据填充数据库表。”

如果您想在数据结构已更改时进行一些动态数据更新,则可以根据需要直接在迁移中运行原始查询。因此,例如,如果您在up方法中添加了一些列,则可以根据您的业务逻辑更新数据库中的行,例如:

// Add column, allow null at first
await queryInterface.addColumn("users", "user_type", {
    type: Sequelize.STRING,
    allowNull: true
});

// Update data
await queryInterface.sequelize.query("UPDATE users SET user_type = 'simple_user' WHERE is_deleted = 0;");

// Change column, disallow null
await queryInterface.changeColumn("users", "user_type", {
    type: Sequelize.STRING,
    allowNull: false
});
Run Code Online (Sandbox Code Playgroud)

Google Groups 中也有关于这个话题的有趣讨论。我希望这可以帮助你。