一个迁移文件中的多个迁移语句

Pre*_*ain 10 migration error-handling node.js sequelize.js sails.js

我试图在单个迁移文件中执行多个迁移语句,以便一次更改同一个表的多个列.

我想知道我是否以书写方式进行,或者是否有更好,更合适的方法:

迁移代码

module.exports = {
    up: function(queryInterface, Sequelize, done) {

        queryInterface.changeColumn('users', 'name', {
            type: Sequelize.STRING,
            allowNull: false,
            require: true,
            unique: true
        }).success(function() {
            queryInterface.changeColumn('users', 'address', {
                type: Sequelize.STRING,
                allowNull: false,
                require: true,
                unique: true
            }).success(function() {
                queryInterface.changeColumn('users', 'city', {
                    type: Sequelize.STRING,
                    allowNull: false,
                    require: true,
                    unique: true
                }).success(function() {
                    queryInterface.changeColumn('users', 'state', {
                        type: Sequelize.STRING,
                        allowNull: false,
                        require: true,
                        defaultValue: "ncjnbcb"
                    });
                    done();
                });
            });
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

但是我面临一个错误:

TypeError:undefined不是函数

由于我在迁移中找不到任何调试错误的方法,如果有人帮助我解决它或者如果可能的话,告诉我们如何找出迁移中的错误的方式将是很好的.

Aid*_*les 15

你的TypeError可能是因为你没有返回任何东西.该文件说,每个迁移函数返回一个承诺.没有提到done回调.

为此,请尝试以下方法:

return Promise.all([
  queryInterface.changeColumn..., 
  queryInterface.changeColumn...
]);
Run Code Online (Sandbox Code Playgroud)

  • 这个方法不太对。那里任何失败的查询都会导致迁移陷入困境。请参阅 https://github.com/sequelize/cli/issues/133#issuecomment-236402184 (2认同)

Fir*_*ani 13

module.exports = {
  up: async (queryInterface, Sequelize) => {
    try {
      await queryInterface.addColumn('User', 'name', {
        type: Sequelize.STRING
      });
      await queryInterface.addColumn('User', 'nickname', {
        type: Sequelize.STRING
      });
      return Promise.resolve();
    } catch (e) {
      return Promise.reject(e);
    }
  },

  down: async (queryInterface, Sequelize) => {
    try {
      await queryInterface.removeColumn('Challenges', 'name');
      await queryInterface.removeColumn('Challenges', 'nickname');
      return Promise.resolve();
    } catch (e) {
      return Promise.reject(e);
    }
  }
};
Run Code Online (Sandbox Code Playgroud)


Asw*_*kan 9

Promise.all与事务一起使用(更安全的迁移):

module.exports = {
  up: async (queryInterface, Sequelize) => {
    return queryInterface.sequelize.transaction(t => {
      return Promise.all([
        queryInterface.changeColumn('users', 'name', 
          { type: Sequelize.STRING },
          { transaction: t }
        ),
        queryInterface.changeColumn('users', 'address', 
          { type: Sequelize.STRING },
          { transaction: t }
        ),
        queryInterface.changeColumn('users', 'city', 
          { type: Sequelize.STRING },
          { transaction: t }
        )
      ]);
    });
  },

  down: async (queryInterface, Sequelize) => {
    return queryInterface.sequelize.transaction((t) => {
      return Promise.all([
        queryInterface.removeColumn('users', 'name', { transaction: t }),
        queryInterface.removeColumn('users', 'address', { transaction: t }),
        queryInterface.removeColumn('users', 'city', { transaction: t })
      ])
    })
  }
};
Run Code Online (Sandbox Code Playgroud)

Promise.all如果某些查询被拒绝,则在不使用事务的情况下使用会导致问题。使用事务是安全的,这样所有操作都将成功执行或不进行任何更改。


Bri*_*ink 5

所以这是 2 个答案的组合。

@Firmino Changani - 效果很好,但即使有些失败也会完成一些迁移

@Aswin Sanakan - 意味着它们全部工作或没有迁移,但如果第二次迁移依赖于第一次迁移,它将不起作用

我正在创建一个表并向该表添加一个特殊索引。所以我最终将它们结合起来,以下内容对我有用:

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    return queryInterface.sequelize.transaction(async t => {
      try {
        await queryInterface.createTable(
          'phonenumbers',
          {
            id: {
              allowNull: false,
              autoIncrement: true,
              primaryKey: true,
              type: Sequelize.INTEGER
            },
            full_number: {
              type: Sequelize.STRING,
              unique: true
            },
            phone: {
              type: Sequelize.STRING
            },
            extension: {
              type: Sequelize.INTEGER,
            },
            country_id: {
              type: Sequelize.INTEGER
            },
            is_valid_format: {
              type: Sequelize.BOOLEAN
            },
            type: {
              type: Sequelize.STRING
            },
            createdAt: {
              allowNull: false,
              type: Sequelize.DATE
            },
            updatedAt: {
              allowNull: false,
              type: Sequelize.DATE
            },
          },
          { transaction: t }
        ),
        await queryInterface.addIndex(
          'phonenumbers',
          ['phone'],
          {
            name: 'constraint-phone-extension',
            where: {extension: null},
            transaction: t
          }
        )
        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    });
  },
  down: async (queryInterface, Sequelize) => {
    return queryInterface.sequelize.transaction(async t => {
      try {
        await queryInterface.dropTable('phonenumbers', { transaction: t }),
        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    })
  }
};
Run Code Online (Sandbox Code Playgroud)