Sequelize and the Sequelize CLI: Migrations
I recently started another personal project (a wiki) with a Node/Express back-end, and decided that using a relational database would make the most sense. Since most of my recent projects have used Mongo, not SQL, I decided it was time for me to revisit one of Node's SQL ORMs: Sequelize.
Setting up migrations with the sequelize-cli is actually much easier than Sequelize's migration documentation makes it seem. (Though, to be fair, I did learn most of the following at one of the 2 links in this paragraph).
Anyway, I decided to write up a quick, fast introduction to setting up Sequelize migrations for a Node application.
Pre-requisites
This tutorial assumes that you know how to set up a basic Node/Express application (or are planning to learn).
If this doesn't describe you, feel free to catch up by following along at one of my other blog posts on that subject.
Walk-through
Step 1: Install sequelize
First of all, make sure your application has sequelize
and sequelize-cli
installed.
- Navigate to your app's root directory in the terminal
npm install --save sequelize
npm install --save-dev sequelize-cli
Note that you can use --save
for both--it only affects where in your package.json
file the dependencies will be listed.
Step 2: Configure sequelize CLI
The Sequelize CLI allows you to set up and run migrations directly from your terminal. However, it uses a default file structure which may not work for your application.
To fix this, you should now create a file called .sequelizerc
in the root directory of your node app. Open up this file in a text editor, and enter the following:
var path = require('path');
module.exports = {
'config': path.resolve('path/to/folder', 'config/config.json'),
'migrations-path': path.resolve('path/to/folder', 'migrations'),
'models-path': path.resolve('path/to/folder, 'models')
}
As you may guess, this file specifies where the sequelize CLI should expect the config file, the migrations folder, and the models folder. path
is simply a built-in node module, and path.resolve
simply outputs a file path (a string).
Feel free to enter whatever paths make sense for your application.
Step 3: Initialize sequelize
Now that you have the sequelize CLI installed via npm
and configured via the .sequelizerc
file, run sequelize init
.
This will create a config file and folders for migrations and models at the locations specified in step 2.
At this point, I would recommend opening up the config.json
file that was just created by the sequelize init
command. In this file, you will see the configuration for your development
, test
, and production
databases.
I chose to use sqlite3
for my database, so I put the following in my config.json
file:
{
"development": {
"dialect": "sqlite",
"storage": "path/to/folder/dev_database.sqlite"
},
"test": {
"dialect": "sqlite",
"storage": "path/to/folder/test_database.sqlite"
},
"production": {
"dialect": "sqlite",
"storage": "path/to/folder/prod_database.sqlite"
}
}
At this point, depending on whether you're using SQLite
, MySQL
, or some other type of database, some additional setup may be required here. My advice is to use SQLite
if you're just trying to get a proof of concept working.
Step 4: Create a migration file
Ok, at this point you're hopefully all set up. Time to create a migration!
One option (don't do this quite yet) is to run the following command from a terminal: sequelize db:migrate --name="my-first-migration"
Feel free to name the migration whatever you like: sequelize-cli
will automatically create a migration file with whatever name you choose, prepended with a timestamp. You can then open up that file and update it as you like (the docs may help if you go that route).
However, an (in my opinion) easier option is to use a different command: sequelize model:create
. If you're curious, you can check out the inline docs for this command with sequelize help:model:create
.
Since I wanted to create a Page
model for storing the pages of my wiki application, I ran the following command:
sequelize model:create --name Page --attributes "name:string, text:text, url:string"
Which auto-created a Page model and a corresponding migration. Feel free to run this command, or a similar one that fits your application's need.
Either way, you should now have a new migration file in your migrations folder.
Step 6: Run the migration
All the hard work is done at this point. You now have a new file in your migrations folder, so at this point the only step remaining is to run it.
sequelize db:migrate
BOOM! Now you have a database, models, migrations, etc. Any time you want to update your database, simply add more migrations and run them whenever.
Quick Note:
The auto-generated migration code resulting from sequelize model:create
uses the done
callback, which is no longer in use depending on what version of the sequelize CLI you have installed. The issue and the fix are described in this gist if you are running into this error.
Tl;Dr: If you get this error, get rid of the done
callback in your code.