Imagine you were working with Sequelize and after setting up the database and models you ran the command to migrate and everything worked well. You checked the database(local) via psql(or any other client of choice) and saw that everything was intact. You were happy with yourself but suddenly you realized that you forgot to add a column to that model, you quickly made some changes to the migration file, ran the migration command again but nothing happened. You became downcast and you were thinking of recreating the models and migrating them again but you decided to check google to see if there was a way to salvage the situation and suddenly you stumbled upon this article. You just struck gold!
The technologies to be used are Javascript(ES6), expressjs and Sequelize ORM.
I will assume you already created a database and you just want to make the necessary changes to the table(s). However, you can follow along for learning purposes.
Now create a folder called sequelize-migrations or whatever you want to call it and go into it like so.
mkdir sequelize-migrations && cd sequelize-migrations
Go here and npm install the packages in package.json then do the following.
- Create the following files .babelrc and .sequelizerc and add the contents of the respective files of the above repository into your code.
- Run npx sequelize-cli init command. It will create the folders specified in .sequelizerc file.
- Replace the default content of database/config/config.js with the version of what is in the above repository.
- Do same for database/models/index.js
- Create a database(local) and put the database url in a .env file.
Enter this command to create the model
npx sequelize-cli model:generate --name User --attributes name:string,email:string
Enter this command to migrate the models into the created database
npx sequelize-cli db:migrate
According to the sequelize docs, it is only when you run the above command that you create the table specified in the models folder meaning that the database/table has been empty all along.
Everything worked well and suddenly you remembered that you forgot to add username and date_of_birth columns and you would also like to remove email. You made some changes to the migration/model file and ran the migration command again but you saw
No migrations were executed, database schema was already up to date
One thing worthy of note from the sequelize docs is that migrations help sequelize to keep track of changes to the database as it is written
...with migrations you can transfer your existing database into another state and vice versa...
This means the previously generated migration file has done its job and now you have to create another.
SOLUTION
Enter the following command into your terminal
npx sequelize-cli migration:create --name create-users-two
I chose file name as create-users-two so feel free to choose yours.
Open the new migration file generated and add the code below:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id:
Sequelize.INTEGER });
*/
return Promise.all([queryInterface.addColumn(
'Users',
'username',
Sequelize.STRING
),
queryInterface.addColumn(
'Users',
'date_of_birth',
Sequelize.DATE
),
queryInterface.removeColumn(
'Users',
'email',
Sequelize.STRING
)
]);
},
down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
return queryInterface.dropTable('Users');
}
};
- The up function will run when we run the migration command.
- Inside the addColumn function there are three arguments: tablename, column to be added and datatype.
- removeColumn function also takes in same arguments to remove a column.
- The down function signifies what should happen when you undo migration.
- Sequelize migrations by default expects a promise to be returned. In order to avoid unwanted behaviour and so as to achieve the default behaviour, we have wrapped everything in a
Promise.all
.
Now re-run the migration command npx sequelize-cli db:migrate and check your local database for confirmation. If all went well, you just solved the problem you had. If you want to make another change to the table, you will have to create another migration file and specify what you want in the up and down functions. You can also read more about sequelize query interface.
I know you are happy. Thanks for coming to my Ted Talks!
Top comments (4)
Hello!
Thank you for sharing this post.
I just want to check if you're aware that if we revert this migration we'll lose the table and running the migration back it won't work as the table was dropped.
I'd suggest that instead of dropping the table, you just remove added columns.
p.s: it'd even be better if you write the title in small letters.
Here's an example of how I work with migration.
What you can notice here:
up
function, I do the same, but in reverse order, in thedown
functionup
, I remove them indown
Hope this can help you understand how I work with migrations.
Excellent tutorial, just what I was searching for, but, it's necessary delete all table in down function? I mean, should this undo the changes of adding cols?
Thanks for the feedback and glad it helped. You can put whatever you want in the down function depending on your use case.