Sequelize js ,我们如何在迁移中更改列类型

jun*_*ey 5 javascript node.js sequelize.js feathers-sequelize

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

#迁移 1

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

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

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

小智 16

您可以使用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,
            })
        ])
    }
};
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 15

changeColumn需要注意的错误

我对 6.5.1 上的内容感到非常困惑,所以我认为最好在这里留下警告。

Bug 1:SQLite 触发删除级联

SQLite 没有ALTER COLUMN如下所述:

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

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

值得庆幸的是,在我的用例中,这并不重要,因为 SQLite 只是一种本地开发的快速方法,所以如果它每次都会对数据库进行核攻击,那也没什么问题,因为我可以重新播种它。实际上考虑到 Sequelize 对不同 DBMS 的支持不一致,在本地使用 SQLite 是一个坏习惯。

type:Bug 2:即使你不改变它,你也必须传递PostgreSQL

例如,如果您只想更改列的默认值,您可能需要执行以下操作:

  up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async transaction => {
    await queryInterface.changeColumn('User', 'ip',
      {
        defaultValue: undefined,
      }, { transaction }
    );
  })
Run Code Online (Sandbox Code Playgroud)

但在 PostgreSQL 上会出现错误:

ERROR: Cannot read property 'toString' of undefined
Run Code Online (Sandbox Code Playgroud)

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

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

否则它会尝试执行以下操作type.toString()https://github.com/sequelize/sequelize/blob/v6.5.1/lib/dialects/postgres/query-generator.js#L466type未定义。

  • Bug 2 也适用于 mysql-dialect(在我的例子中为 MariaDB)。你刚刚让我免于花几个小时去研究那些代码。谢谢你! (2认同)