NodeJS 了解Sequelize数据库迁移和种子

sh7euo9m  于 2023-05-28  发布在  Node.js
关注(0)|答案(3)|浏览(181)

我试图把我的头围绕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");
  }
};

再次运行迁移将只运行第二个迁移,因为数据库中保存了第一个迁移已经执行的信息。但默认情况下,续集重新运行所有播种机。那么,我应该调整seeders/01-demo-user.js或更改默认行为,并将种子存储在数据库中,然后创建一个新的种子来更新firstname吗?
如果firstname不能是null,那么首先运行迁移,然后运行旧版本的seeders/01-demo-user.js会抛出错误,因为firstname不能是null
重新运行seeder会导致另一个问题:已经有一个使用demo@demo.com电子邮件的用户。第二次运行它将复制该用户。或者我必须在播种机里检查这样的东西吗?
以前,我只是在迁移中添加了用户帐户,这样我就可以确定何时将其添加到数据库以及何时必须更新它。但是有人告诉我,我做得全错了,我必须使用播种机来完成这样的任务。
任何帮助/见解非常感谢。

arknldoa

arknldoa1#

在我看来,种子是只运行一次的东西,而迁移是不断地逐层添加到数据库结构中的东西。
我会使用seeders来填充一些查找或其他数据,这些数据很可能不会改变,或者测试数据。在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
});

在Google Groups中也有关于这个主题的有趣讨论。

eh57zj3b

eh57zj3b2#

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

yr9zkbsy

yr9zkbsy3#

您好,尝试使用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')
};

相关问题