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
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(),
);
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.
psql $DB_DSN
For list of tables
\dt
For contents of schema_migrations
SELECT * FROM schema_migrations;
| 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.