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.
Solution 1:
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
});
Solution 2:
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()"