Performing Atlas Migrations When Using Golang Migrate
Developers who use Atlas to run migrations using a golang-migrate directory format, may run into an errors like:
-- migrating version 20250324061649.down.sql
-> DROP TABLE `users`;
Error 1051 (42S02): Unknown table 'public.users'
golang-migrate is a popular migration tool used in the Go community, and Atlas supports working with its migration directory
format, amongst others, through basic configurations.
golang-migrate Migration Directory
When creating schema migrations with golang-migrate, users create two empty files for each set of changes like so:
db/migrations
├── 20250324061649.down.sql
└── 20250324061649.up.sql
The files contain the intended schema changes (up) and the instructions to roll back these changes (down).
When applying migrations, you use the up command so golang-migrate knows to use the corresponding up files. When
rolling back on migrations, you use the down command to golang-migrate knows to use the corresponding down files.
Applying Migrations with Atlas
The standard migrations directory for Atlas does not contain separate up and down files. Instead, it only contains
files with schema migrations and applies them all in order when running migrate apply and has a separate system for rollbacks.
If a user tries executing migrate apply using a golang-migrate migrations directory setup without any flags, Atlas will
assume it is a standard Atlas directory and run all the files, including the down files. Since Atlas runs the migration
files in lexicographic order, the down files are typically run first, meaning that Atlas tries to run commands that revert
changes that have yet to be made, leading to errors.
The Solution
To ensure that only the up migration files are run, add the format flag to the env block in atlas.hcl either as
a parameter:
env "dev" {
...
migration {
dir = "file://db/migrations"
format = "golang-migrate"
}
}
or as a flag in the directory link:
env "dev" {
...
migration {
dir = "file://db/migrations?format=golang-migrate"
}
}
Alternatively, you can include the directory link with the ?format=golang-migrate flag in the command:
atlas migrate apply --dir "file://db/migrations?format=golang-migrate" --env dev
Defining a format value ensures that Atlas is aware that both up and down files exist in the migrations directory
and it should only use the up files. These up files can have destructive commands in them, but they are not dropping
objects that don't yet exist in the schema.