【问题标题】:Sequelize js , how do we change column type in migrationSequelize js,我们如何在迁移中更改列类型
【发布时间】:2020-10-21 08:04:40
【问题描述】:

我们如何在迁移中更改列类型。在我的迁移 1 中,我有一个添加了该列的迁移。现在我想将列类型从字符串更改为文本,我应该创建一个类似于 changeColumn 的新迁移文件,还是可以创建与迁移 1 相同的新迁移文件,但我只需将类型更改为文本?谢谢。

#迁移 1

await queryInterface.addColumn(SampleModel.tableName, 'name', {
  type: Sequelize.STRING,
  allowNull: true,
}, {
  transaction,
});

迁移 2(创建新迁移会像这样工作吗?仍然 addColumn 但我将类型更改为文本)

  await queryInterface.addColumn(SampleModel.tableName, 'name', {
      type: Sequelize.TEXT,
      allowNull: true,
    }, {
      transaction,
    });

【问题讨论】:

    标签: javascript node.js sequelize.js feathers-sequelize


    【解决方案1】:

    您可以在迁移 2 中使用 changeColumn 而不是 addColumn

    来自the documentation

    可以更改默认值、允许为 null 或数据类型。

    【讨论】:

      【解决方案2】:

      您可以使用changeColumn 代替addColumn,因为addColumn 将在您的表格中添加新列。 你可以这样定义你的迁移:

      迁移文件

      module.exports = {
          up: (queryInterface, Sequelize) => {
              return Promise.all([
                  queryInterface.changeColumn('your table name ', 'name', {
                      type: Sequelize.TEXT,
                      allowNull: true,
                  }, {
                      transaction,
                  })
              ])
          },
      
          down: (queryInterface, Sequelize) => {
              return Promise.all([
                  queryInterface.changeColumn('your table name ', 'name', {
                      type: Sequelize.STRING,
                      allowNull: true,
                  }, {
                      transaction,
                  })
              ])
          }
      };
      

      【讨论】:

      • 啊,所以迁移的失败是类型:Sequelize.STRING, ?
      • 如果您想撤消迁移,它会将您的类型设置为较旧的类型,即STRING
      • 如果列已经存在,我还需要调用 if (!Object.keys(tableDef).includes('name')) { ?
      【解决方案3】:

      changeColumn 需要注意的错误

      我真的被 6.5.1 的那些人弄糊涂了,所以我认为在这里留下警告会很好。

      错误 1:删除级联时 SQLite 触发器

      SQLite 没有ALTER COLUMN,如下所述:

      问题是 sequelize 不需要 ON DELETE CASCADE 执行此操作,因此当它摆脱原始表以重新创建它时,这会触发级联,因此您会丢失数据。

      他们需要做的是在迁移之前暂时删除所有级联,然后在之后恢复它们。我不知道如何解决这个问题,除非围绕一个迁移,一个迁移会丢弃级联,另一个迁移会恢复级联。

      谢天谢地,在我的用例中,这并不重要,因为 SQLite 只是一种在本地开发的快速方法,所以如果它每次都对数据库进行核对就可以了,因为我可以重新植入它。考虑到 Sequelize 对不同 DBMS 的支持之间存在不一致,在本地使用 SQLite 是一个坏习惯。

      错误 2:您必须在 PostgreSQL 上传递 type:,即使您不更改它

      例如,如果您只想更改列的默认值,您可能会这样做:

          await queryInterface.changeColumn('User', 'ip',
            {
              defaultValue: undefined,
            }, { transaction }
          );
      

      但在 PostgreSQL 上会报错:

      ERROR: Cannot read property 'toString' of undefined
      

      由于某种原因,它没有提供回溯,我喜欢 Node.js 及其生态系统,所以经过一个小时的调试后,我发现type 是必需的。假设列的类型为DataTypes.STRING,我们会这样做:

          await queryInterface.changeColumn('User', 'ip',
            {
              type: Sequelize.DataTypes.STRING,
              defaultValue: undefined,
            }, { transaction }
          );
      

      否则它会尝试在https://github.com/sequelize/sequelize/blob/v6.5.1/lib/dialects/postgres/query-generator.js#L466 处执行type.toString(),但type 未定义。

      【讨论】:

        猜你喜欢
        • 2017-12-05
        • 2017-07-28
        • 1970-01-01
        • 2017-01-11
        • 2016-07-18
        • 1970-01-01
        • 2015-10-12
        • 2019-05-27
        • 1970-01-01
        相关资源
        最近更新 更多