Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update migrations.md #707

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions versioned_docs/version-6.x.x/other-topics/migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
title: Migrations
---

Just like you use [version control](https://en.wikipedia.org/wiki/Version_control) systems such as [Git](https://en.wikipedia.org/wiki/Git) to manage changes in your source code, you can use **migrations** to keep track of changes to the database. With migrations you can transfer your existing database into another state and vice versa: Those state transitions are saved in migration files, which describe how to get to the new state and how to revert the changes in order to get back to the old state.
Just like you use [version control](https://en.wikipedia.org/wiki/Version_control) systems such as [Git](https://en.wikipedia.org/wiki/Git) to manage changes in your source code, you can use **migrations** to keep track of changes to the database. With migrations, you can transfer your existing database into another state and vice versa: Those state transitions are saved in migration files, which describe how to get to the new state and how to revert the changes in order to get back to the old state.

You will need the [Sequelize Command-Line Interface (CLI)](https://github.com/sequelize/cli). The CLI ships support for migrations and project bootstrapping.

A Migration in Sequelize is a javascript file which exports two functions, `up` and `down`, that dictates how to perform the migration and undo it. You define those functions manually, but you don't call them manually; they will be called automatically by the CLI. In these functions, you should simply perform whatever queries you need, with the help of `sequelize.query` and whichever other methods Sequelize provides to you. There is no extra magic beyond that.
A Migration in Sequelize is a javascript file that exports two functions, `up` and `down`, that dictate how to perform the migration and undo it. You define those functions manually, but you don't call them manually; they will be called automatically by the CLI. In these functions, you should simply perform whatever queries you need, with the help of `sequelize.query` and whichever other methods Sequelize provides to you. There is no extra magic beyond that.

## Installing the CLI

Expand All @@ -28,14 +28,14 @@ npx sequelize-cli init

This will create following folders

- `config`, contains config file, which tells CLI how to connect with database
- `config`, contains the config file, which tells CLI how to connect with the database
- `models`, contains all models for your project
- `migrations`, contains all migration files
- `seeders`, contains all seed files

### Configuration

Before continuing further we will need to tell the CLI how to connect to the database. To do that let's open default config file `config/config.json`. It looks something like this:
Before continuing further, we must tell the CLI how to connect to the database. To do that let's open the default config file `config/config.json`. It looks something like this:

```json
{
Expand Down Expand Up @@ -63,17 +63,17 @@ Before continuing further we will need to tell the CLI how to connect to the dat
}
```

Note that the Sequelize CLI assumes mysql by default. If you're using another dialect, you need to change the content of the `"dialect"` option.
Note that the Sequelize CLI assumes MySQL by default. If you're using another dialect, you need to change the content of the `"dialect"` option.

Now edit this file and set correct database credentials and dialect. The keys of the objects (e.g. "development") are used on `model/index.js` for matching `process.env.NODE_ENV` (When undefined, "development" is a default value).

Sequelize will use the default connection port for each dialect (for example, for postgres, it is port 5432). If you need to specify a different port, use the `"port"` field (it is not present by default in `config/config.js` but you can simply add it).
Sequelize will use the default connection port for each dialect (for example, for Postgres, it is port 5432). If you need to specify a different port, use the `"port"` field (it is not present by default in `config/config.js` but you can simply add it).

**Note:** _If your database doesn't exist yet, you can just call `db:create` command. With proper access it will create that database for you._
**Note:** _If your database doesn't exist yet, you can just call `db:create` command. With proper access, it will create that database for you._

## Creating the first Model (and Migration)

Once you have properly configured CLI config file you are ready to create your first migration. It's as simple as executing a simple command.
Once you have properly configured the CLI config file you are ready to create your first migration. It's as simple as executing a simple command.

We will use `model:generate` command. This command requires two options:

Expand All @@ -89,9 +89,9 @@ npx sequelize-cli model:generate --name User --attributes firstName:string,lastN
This will:

- Create a model file `user` in `models` folder;
- Create a migration file with name like `XXXXXXXXXXXXXX-create-user.js` in `migrations` folder.
- Create a migration file with a name like `XXXXXXXXXXXXXX-create-user.js` in the `migrations` folder.

**Note:** _Sequelize will only use Model files, it's the table representation. On the other hand, the migration file is a change in that model or more specifically that table, used by CLI. Treat migrations like a commit or a log for some change in database._
**Note:** _Sequelize will only use Model files, it's the table representation. On the other hand, the migration file is a change in that model or more specifically that table, used by CLI. Treat migrations like a commit or a log for some change in the database._

## Running Migrations

Expand All @@ -103,21 +103,21 @@ npx sequelize-cli db:migrate

This command will execute these steps:

- Will ensure a table called `SequelizeMeta` in database. This table is used to record which migrations have run on the current database
- Start looking for any migration files which haven't run yet. This is possible by checking `SequelizeMeta` table. In this case it will run `XXXXXXXXXXXXXX-create-user.js` migration, which we created in last step.
- Will ensure a table called `SequelizeMeta` in the database. This table is used to record which migrations have run on the current database
- Start looking for any migration files that haven't run yet. This is possible by checking the `SequelizeMeta` table. In this case, it will run the `XXXXXXXXXXXXXX-create-user.js` migration, which we created in the last step.
- Creates a table called `Users` with all columns as specified in its migration file.

## Undoing Migrations

Now our table has been created and saved in the database. With migration you can revert to old state by just running a command.
Now our table has been created and saved in the database. With migration, you can revert to the old state by just running a command.

You can use `db:migrate:undo`, this command will revert the most recent migration.

```text
npx sequelize-cli db:migrate:undo
```

You can revert back to the initial state by undoing all migrations with the `db:migrate:undo:all` command. You can also revert back to a specific migration by passing its name with the `--to` option.
You can revert to the initial state by undoing all migrations with the `db:migrate:undo:all` command. You can also revert to a specific migration by passing its name with the `--to` option.

```text
npx sequelize-cli db:migrate:undo:all --to XXXXXXXXXXXXXX-create-posts.js
Expand All @@ -127,17 +127,17 @@ npx sequelize-cli db:migrate:undo:all --to XXXXXXXXXXXXXX-create-posts.js

Suppose we want to insert some data into a few tables by default. If we follow up on the previous example we can consider creating a demo user for the `User` table.

To manage all data migrations you can use seeders. Seed files are some change in data that can be used to populate database tables with sample or test data.
To manage all data migrations you can use seeders. Seed files are some changes in data that can be used to populate database tables with sample or test data.

Let's create a seed file which will add a demo user to our `User` table.
Let's create a seed file that will add a demo user to our `User` table.

```text
npx sequelize-cli seed:generate --name demo-user
```

This command will create a seed file in `seeders` folder. File name will look something like `XXXXXXXXXXXXXX-demo-user.js`. It follows the same `up / down` semantics as the migration files.
This command will create a seed file in the `seeders` folder. The file name will look something like `XXXXXXXXXXXXXX-demo-user.js`. It follows the same `up / down` semantics as the migration files.

Now we should edit this file to insert demo user to `User` table.
Now we should edit this file to insert the demo user to the `User` table.

```js
module.exports = {
Expand All @@ -158,7 +158,7 @@ module.exports = {

## Running Seeds

In last step you created a seed file; however, it has not been committed to the database. To do that we run a simple command.
In the last step you created a seed file; however, it has not been committed to the database. To do that we run a simple command.

```text
npx sequelize-cli db:seed:all
Expand Down Expand Up @@ -211,7 +211,7 @@ We can generate this file using `migration:generate`. This will create `xxx-migr
npx sequelize-cli migration:generate --name migration-skeleton
```

The passed `queryInterface` object can be used to modify the database. The `Sequelize` object stores the available data types such as `STRING` or `INTEGER`. Function `up` or `down` should return a `Promise`. Let's look at an example:
The passed `queryInterface` object can be used to modify the database. The `Sequelize` object stores the available data types such as `STRING` or `INTEGER`. The function `up` or `down` should return a `Promise`. Let's look at an example:

```js
module.exports = {
Expand All @@ -231,7 +231,7 @@ module.exports = {
};
```

The following is an example of a migration that performs two changes in the database, using an automatically-managed transaction to ensure that all instructions are successfully executed or rolled back in case of failure:
The following is an example of a migration that performs two changes in the database, using an automatically managed transaction to ensure that all instructions are successfully executed or rolled back in case of failure:

```js
module.exports = {
Expand Down Expand Up @@ -289,7 +289,7 @@ module.exports = {
}
```

The next example is of a migration that uses async/await where you create an unique index on a new column, with a manually-managed transaction:
The next example is of a migration that uses async/awaits where you create a unique index on a new column, with a manually-managed transaction:

```js
module.exports = {
Expand Down Expand Up @@ -332,7 +332,7 @@ module.exports = {
};
```

The next example is of a migration that creates an unique index composed of multiple fields with a condition, which allows a relation to exist multiple times but only one can satisfy the condition:
The next example is of a migration that creates a unique index composed of multiple fields with a condition, which allows a relation to exist multiple times but only one can satisfy the condition:

```js
module.exports = {
Expand Down Expand Up @@ -375,7 +375,7 @@ This is a special configuration file. It lets you specify the following options

Some scenarios where you can use it:

- You want to override default path to `migrations`, `models`, `seeders` or `config` folder.
- You want to override the default path to the `migrations`, `models`, `seeders`, or `config` folder.
- You want to rename `config.json` to something else like `database.json`

And a whole lot more. Let's see how you can use this file for custom configuration.
Expand All @@ -395,18 +395,18 @@ module.exports = {
};
```

With this config you are telling the CLI to:
With this config, you are telling the CLI to:

- Use `config/database.json` file for config settings;
- Use the `config/database.json` file for config settings;
- Use `db/models` as models folder;
- Use `db/seeders` as seeders folder;
- Use `db/migrations` as migrations folder.
- Use `db/migrations` as the migrations folder.

### Dynamic configuration

The configuration file is by default a JSON file called `config.json`. But sometimes you need a dynamic configuration, for example to access environment variables or execute some other code to determine the configuration.
The configuration file is by default a JSON file called `config.json`. But sometimes you need a dynamic configuration, for example, to access environment variables or execute some other code to determine the configuration.

Thankfully, the Sequelize CLI can read from both `.json` and `.js` files. This can be setup with `.sequelizerc` file. You just have to provide the path to your `.js` file as the `config` option of your exported object:
Thankfully, the Sequelize CLI can read from both `.json` and `.js` files. This can be setup with the `.sequelizerc` file. You just have to provide the path to your `.js` file as the `config` option of your exported object:

```js
const path = require('path');
Expand Down Expand Up @@ -504,7 +504,7 @@ There are three types of storage that you can use: `sequelize`, `json`, and `non

#### Migration Storage

By default the CLI will create a table in your database called `SequelizeMeta` containing an entry for each executed migration. To change this behavior, there are three options you can add to the configuration file. Using `migrationStorage`, you can choose the type of storage to be used for migrations. If you choose `json`, you can specify the path of the file using `migrationStoragePath` or the CLI will write to the file `sequelize-meta.json`. If you want to keep the information in the database, using `sequelize`, but want to use a different table, you can change the table name using `migrationStorageTableName`. Also you can define a different schema for the `SequelizeMeta` table by providing the `migrationStorageTableSchema` property.
By default, the CLI will create a table in your database called `SequelizeMeta` containing an entry for each executed migration. To change this behavior, there are three options you can add to the configuration file. Using `migrationStorage`, you can choose the type of storage to be used for migrations. If you choose `json`, you can specify the path of the file using `migrationStoragePath` or the CLI will write to the file `sequelize-meta.json`. If you want to keep the information in the database, using `sequelize`, but want to use a different table, you can change the table name using `migrationStorageTableName`. Also, you can define a different schema for the `SequelizeMeta` table by providing the `migrationStorageTableSchema` property.

```json
{
Expand Down Expand Up @@ -534,7 +534,7 @@ By default the CLI will create a table in your database called `SequelizeMeta` c

#### Seed Storage

By default the CLI will not save any seed that is executed. If you choose to change this behavior (!), you can use `seederStorage` in the configuration file to change the storage type. If you choose `json`, you can specify the path of the file using `seederStoragePath` or the CLI will write to the file `sequelize-data.json`. If you want to keep the information in the database, using `sequelize`, you can specify the table name using `seederStorageTableName`, or it will default to `SequelizeData`.
By default, the CLI will not save any seed that is executed. If you choose to change this behavior (!), you can use `seederStorage` in the configuration file to change the storage type. If you choose `json`, you can specify the path of the file using `seederStoragePath` or the CLI will write to the file `sequelize-data.json`. If you want to keep the information in the database, using `sequelize`, you can specify the table name using `seederStorageTableName`, or it will default to `SequelizeData`.

```json
{
Expand Down Expand Up @@ -580,4 +580,4 @@ Use the command like so: `npm run migrate:up -- --url <url>`

### Programmatic usage

Sequelize has a sister library called [umzug](https://github.com/sequelize/umzug) for programmatically handling execution and logging of migration tasks.
Sequelize has a sister library called [umzug](https://github.com/sequelize/umzug) for programmatically handling the execution and logging of migration tasks.
Loading