Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a table and add indexes in a single migration with Sequelize

What is the correct way to create a table and add indices on some of its columns in a single migration?

Example Migration: 2012341234-create-todo.js

How would I create an index on the "author_id" and "title" column?

'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');   } }; 

The Sequelize docs indicate that an index would be added like this:

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

Can these methods just be chained? Do "up" and "down" just need to return a promise? I'm not seeing anything in the docs about it.

like image 685
Don P Avatar asked Mar 09 '17 23:03

Don P


People also ask

How do I add a column in migration Sequelize?

To add or delete columns in Sequelize CLI, we can use the sequelize migration:create command to create a migration file. Then we call addColumn to add a column and removeColumn to remove a column in the migration file. to create a migration file. in the migration file.


2 Answers

Yes, the methods can be chained. In your case you just perform the addIndex after createTable method

return queryInterface.createTable('Todos', {     // columns... }).then(() => queryInterface.addIndex('Todos', ['author_id', 'title'])) .then(() => {     // perform further operations if needed }); 
like image 103
piotrbienias Avatar answered Oct 06 '22 21:10

piotrbienias


The accepted solution is problematic if the second step fails. Transactions in each step should be used to allow a roll back to ensure all of the migration steps that are inserts or updates are undone if a problem is encountered at any step. For example:

module.exports = {  up: async (queryIntereface) => {     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;     }   },    down: async (queryInterface) {      etc... 

Reference

  • https://sequelize.org/master/manual/migrations.html#migration-skeleton (search for "transaction()"
like image 30
DeeZone Avatar answered Oct 06 '22 22:10

DeeZone