【问题标题】:Understanding Sequelize database migrations and seeds了解 Sequelize 数据库迁移和种子
【发布时间】:2018-05-28 21:24:30
【问题描述】:

我正试图深入了解 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");
  }
};

很好。如果我想播种(管理员)用户,我可以这样做:

// 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, {});
  }
};

然后为了让魔法发生,我会这样做:

$ sequelize db:migrate

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

$ sequelize db:seed:all

Tataa,现在我在 users 数据库中有一个用户。太好了。

但现在我想将firstname 添加到users 表中,所以我必须添加另一个迁移:

// 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");
  }
};

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

如果firstname 不能是null,那么先运行迁移然后旧版本的seeders/01-demo-user.js 会抛出错误,因为firstname 不能是null

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

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

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

【问题讨论】:

  • 你能解决这个问题吗?我也有同样的问题。
  • 并非如此。现在,如果我正在使用播种机,我也将它们存储在运行它们的数据库中,这样它们就不会再次运行。

标签: node.js database sequelize.js database-migration


【解决方案1】:

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

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

如果您想在数据结构已更改时进行一些动态数据更新,您可以在需要时直接在迁移中运行原始查询。因此,例如,如果您在 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
});

在 Google 网上论坛中也有一个有趣的discussion 关于这个主题。希望对你有帮助。

【讨论】:

  • 这应该是公认的答案。只是遇到了同样的困惑。完美地说。谢谢
  • The Sequelize docs 在声明中混淆了这个问题:“要管理所有数据迁移,您可以使用播种机”。这根本不是真的。有很多原因应该更新迁移文件中的数据,而不是种子。在已建立的应用程序中,迁移文件中的数据更新似乎比播种机更频繁。
  • 如果我编写一些迁移和播种器,它依赖于这些迁移然后添加更多迁移,使播种器对新列无效,我有点困惑......当然,我可以更新新迁移中的数据,但是如果我想创建一个新的数据库会发生什么?新的迁移依赖于首先运行的播种机......我认为真正应该发生的是迁移和播种机的特定顺序。
【解决方案2】:

根据我的经验,迁移会改变结构。播种机...种子数据。最近我在一个没有配置播种机的项目上。 https://sequelize.org/master/manual/migrations.html#seed-storage。这将允许您设置一个文件,这样您的数据就不会被多次播种。迁移配置也在那里。

【讨论】:

    【解决方案3】:

    您好,试试 bulkUpdate...

    'use strict';
    
    module.exports = {
      up: (queryInterface, Sequelize) =>  queryInterface.addColumn(
            'Users',
            'user_type',
            {
              type: Sequelize.STRING,
              allowNull: false,
            }
          ).then(()=>
            queryInterface.bulkUpdate('Users', {
                user_type: 'simple_user',
            }, {
                is_deleted : 0,
            })
          ),
    
      down: (queryInterface, Sequelize) => 
        queryInterface.removeColumn('Users', 'user_type')
    };
    

    【讨论】:

      猜你喜欢
      • 2020-06-04
      • 1970-01-01
      • 2019-12-18
      • 2017-06-26
      • 1970-01-01
      • 2021-07-14
      • 2020-11-09
      • 1970-01-01
      • 2016-07-04
      相关资源
      最近更新 更多