使用Sequelize在单个迁移中创建表并添加索引

时间:2017-03-09 23:35:37

标签: sequelize.js

单次迁移创建表添加索引的正确方法是什么?

迁移示例:2012341234-create-todo.js

如何在“author_id”和“title”列上创建索引?

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Todos', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      author_id: {
        type: Sequelize.INTEGER,
        onDelete: 'CASCADE',
        references: {
          model: 'Authors',
          key: 'id',
          as: 'authorId'
        }
      },
      title: {
        type: Sequelize.STRING
      },

      content: {
        type: Sequelize.TEXT
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Todos');
  }
};

Sequelize文档表明会添加一个索引:

queryInterface.addIndex('Todos', ['author_id', 'title']);

这些方法可以被链接吗? “向上”和“向下”只需要返回一个承诺吗?我在文档中没有看到任何关于它的内容。

5 个答案:

答案 0 :(得分:24)

是的,方法可以链接。在您的情况下,您只需在addIndex方法

之后执行createTable
return queryInterface.createTable('Todos', {
    // columns...
}).then(() => queryInterface.addIndex('Todos', ['author_id', 'title']))
.then(() => {
    // perform further operations if needed
});

答案 1 :(得分:1)

我没有进行交易。我刚刚创建了表并一步添加了索引(唯一索引,这正是我需要的):

    'use strict';
    const { DataTypes } = require('sequelize');

    module.exports = {
      up: async (queryInterface, Sequelize) => {
        return await queryInterface.createTable('exampleTable', {
          id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
          },
          userId: {
              type: DataTypes.INTEGER,
              allowNull: false,
              references: {
                  model: 'user',
                  key: 'id'
              }
          },
          classId: {
              type: DataTypes.INTEGER,
              allowNull: false,
              references: {
                  model: 'class',
                  key: 'id'
              }
          },
      },
      {
          uniqueKeys: {
            unique_tag: {
                customIndex: true,
                fields: ["userId", "classId"]
            }
          }
        });
      },

      down: async (queryInterface, Sequelize) => {
        return await queryInterface.dropTable('exampleTable');
      }
    };

答案 2 :(得分:0)

我使用原始语法创建了一个全新的迁移文件

module.exports = {
 up: (queryInterface) => {
 return queryInterface.sequelize.query('CREATE INDEX devices_mac_uuid ON 
  "Devices" ("mac","uuid")')
 },
 down: (queryInterface) => {
  return queryInterface.sequelize.query('DROP INDEX devices_mac_uuid')
 }
}

答案 3 :(得分:0)

如果第二步失败,则可接受的解决方案会出现问题。如果在任何步骤遇到问题,则应使用每个步骤中的事务来回滚,以确保所有迁移步骤都被撤消。例如:

module.exports = {
 async up: (queryInterface) => {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      await queryInterface.createTable('Todos', {
        // columns...
      }, { transaction });
      await queryInterface.addIndex('Todos', ['author_id', 'title'], { transaction }));


      await transaction.commit();
    } catch (err) {
      await transaction.rollback();
      throw err;
    }
  },

  async down(queryInterface) {

    etc...

参考 -https://sequelize.org/master/manual/migrations.html#migration-skeleton(搜索“ transaction()”

答案 4 :(得分:0)

添加索引的最简单方法

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.addIndex('reports', ['client_id'])
      .then(() => {
        return queryInterface.addIndex('reports', ['report_name'])
      })
      .then(() => {
        return queryInterface.addIndex('reports', ['report_date'])
      })
  },

  down: (queryInterface, Sequelize) => {
    return queryInterface.removeIndex('reports', ['client_id'])
    .then(() => {
      return queryInterface.removeIndex('reports', ['report_name'])
    })
    .then(() => {
      return queryInterface.removeIndex('reports', ['report_date'])
    })
  }
};