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.