Skip to main content

Postgres Migrations Using Go

Installation​

brew install golang-migrate

Verification​

migrate -version

Usage​

Generate a pair of migration files​

migrate create -seq -ext=.sql -dir=./migrations create_abc_table PATH_TO_YOUR_PROJECT/migrations/000001_create_abc_table.up.sql PATH_TO_YOUR_PROJECT/migrations/000001_create_abc_table.down.sql
  • The -seq flag indicates that we want to use sequential numbering like 0001, 0002, ... for the migration files (instead of a Unix timestamp, which is the default).
  • The -ext flag indicates that we want to give the migration files the extension .sql.
  • The -dir flag indicates that we want to store the migration files in the ./migrations directory (which will be created automatically if it doesn’t already exist).
  • The name create_abc_table is a descriptive label that we give the migration

Update content of migration files​

000001_name.up.sql
CREATE TABLE IF NOT EXISTS xyz (
id bigserial PRIMARY KEY,
version integer NOT NULL DEFAULT 1
created_at timestamp(0) with time zone NOT NULL DEFAULT NOW(),
);
000001_name.down.sql
DROP TABLE IF EXISTS xyz;

Executing the migrations​

migrate -path=./migrations -database=$DB_DSN up

Listing the tables​

schema_migrations table is automatically generated by the migrate tool and used to keep track of which migrations have been applied.

terminal
psql $DB_DSN

For list of tables

\dt

For contents of schema_migrations

SELECT * FROM schema_migrations;
output
| version | dirty |
| ------- | ----- |
| 1 | f |

The version column here indicates that our migration files up to (and including) number 1 in the sequence have been executed against the database. The value of the dirty column is false, which indicates that the migration files were cleanly executed without any errors and the SQL statements they contain were successfully applied in full.

Migrating to a specific version​

migrate -path=./migrations -database=$DB_DSN version

Executing down migrations​

migrate -path=./migrations -database=$DB_DSN down

will remove all tables from the database including the schema_migrations

Roll-back by a specific number of migrations​

migrate -path=./migrations -database =$DB_DSN down 1

Forcing migration verion​

When Migration fails, what you need to do is investigate the original error and figure out if the migration file which failed was partially applied. If it was, then you need to manually roll-back the partially applied migration.

Once that’s done, then you must also ‘force’ the version number in the schema_migrations table to the correct value.

migrate -path=./migrations -database=$DB_DSN force 1

Once you force the version, the database is considered ‘clean’ and you should be able to run migrations again without any problem.