To get a feel for how to write migrations, we’ll add a new table to our MusicDB project. We’ve been using the tracks table to keep track of recordings of songs that have appeared on specific albums. However, many artists record songs that they did not write themselves, and certain pieces appear on more than one album. For example, the song “Freddie Freeloader” appears on two different albums in our current dataset. We’ll create a compositions table to track the metadata of the songs that appear in our dataset and later link them to specific tracks records.

Create a new migration

The easiest way to create a new migration is to use the mix task that Ecto provides:

mix ecto.gen.migration

This task has one required argument—the name of the migration we want to create.

Ecto will use this name in the migration module it will create for us. It’s best to make this name as descriptive as possible so that future developers can understand what the migrations do just by looking at the names. We’re going to create a new compositions table, so we’ll call it add_compositions_table.

We can specify the name using the snake case:

mix ecto.gen.migration add_compositions_table

or Pascal case:

mix ecto.gen.migration AddCompositionsTable

Either way, we’ll get the same result. We can pick either of these commands and run it in a terminal window. We’ll see something like this:

* creating priv/repo/migrations
* creating priv/repo/migrations/20210923100737_add_compositions_table.exs

By default, Ecto puts all the migrations it generates into priv/[YOUR_REPO]/migrations. We named our repo Repo, so Ecto uses priv/repo/migrations. Our project only has one repo, so Ecto could infer where to put the migration. If we were using multiple repos, we’d need to specify which one we want to apply the migration to with the -r option:

Get hands-on with 1200+ tech skills courses.