Goose is a database migration tool. Manage your database's evolution by creating incremental SQL files or Go functions.
This is a fork of https://bitbucket.org/liamstask/goose with the following changes:
- No config files
- Default goose binary can migrate SQL files only
- We dropped building .go files on-the-fly in favor of the below
- Import
github.com/pressly/goose
package- To run complex Go migrations with your own
*sql.DB
connection via*sql.Tx
transactions - The pkg doesn't register any SQL drivers anymore (no
panic()
driver conflicts with your codebase!) - The pkg doesn't have any vendor dependencies anymore
- To run complex Go migrations with your own
$ go get -u github.com/pressly/goose/cmd/goose
This will install the goose
binary to your $GOPATH/bin
directory.
Usage: goose [OPTIONS] DRIVER DBSTRING COMMAND
Examples:
goose postgres "user=postgres dbname=postgres sslmode=disable" up
goose mysql "user:password@/dbname" down
goose sqlite3 ./foo.db status
Options:
-dir string
directory with migration files (default ".")
Commands:
up Migrate the DB to the most recent version available
down Roll back the version by 1
redo Re-run the latest migration
status Dump the migration status for the current DB
dbversion Print the current version of the database
create Creates a blank migration template
Create a new Go migration.
$ goose create AddSomeColumns
$ goose: created db/migrations/20130106093224_AddSomeColumns.go
Edit the newly created script to define the behavior of your migration.
You can also create an SQL migration:
$ goose create AddSomeColumns sql
$ goose: created db/migrations/20130106093224_AddSomeColumns.sql
Apply all available migrations.
$ goose up
$ goose: migrating db environment 'development', current version: 0, target: 3
$ OK 001_basics.sql
$ OK 002_next.sql
$ OK 003_and_again.go
Roll back a single migration from the current version.
$ goose down
$ goose: migrating db environment 'development', current version: 3, target: 2
$ OK 003_and_again.go
Roll back the most recently applied migration, then run it again.
$ goose redo
$ goose: migrating db environment 'development', current version: 3, target: 2
$ OK 003_and_again.go
$ goose: migrating db environment 'development', current version: 2, target: 3
$ OK 003_and_again.go
Print the status of all migrations:
$ goose status
$ goose: status for environment 'development'
$ Applied At Migration
$ =======================================
$ Sun Jan 6 11:25:03 2013 -- 001_basics.sql
$ Sun Jan 6 11:25:03 2013 -- 002_next.sql
$ Pending -- 003_and_again.go
Print the current version of the database:
$ goose dbversion
$ goose: dbversion 002
goose supports migrations written in SQL or in Go.
A sample SQL migration looks like:
-- +goose Up
CREATE TABLE post (
id int NOT NULL,
title text,
body text,
PRIMARY KEY(id)
);
-- +goose Down
DROP TABLE post;
Notice the annotations in the comments. Any statements following -- +goose Up
will be executed as part of a forward migration, and any statements following -- +goose Down
will be executed as part of a rollback.
By default, SQL statements are delimited by semicolons - in fact, query statements must end with a semicolon to be properly recognized by goose.
More complex statements (PL/pgSQL) that have semicolons within them must be annotated with -- +goose StatementBegin
and -- +goose StatementEnd
to be properly recognized. For example:
-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )
returns void AS $$
DECLARE
create_query text;
BEGIN
FOR create_query IN SELECT
'CREATE TABLE IF NOT EXISTS histories_'
|| TO_CHAR( d, 'YYYY_MM' )
|| ' ( CHECK( created_at >= timestamp '''
|| TO_CHAR( d, 'YYYY-MM-DD 00:00:00' )
|| ''' AND created_at < timestamp '''
|| TO_CHAR( d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00' )
|| ''' ) ) inherits ( histories );'
FROM generate_series( $1, $2, '1 month' ) AS d
LOOP
EXECUTE create_query;
END LOOP; -- LOOP END
END; -- FUNCTION END
$$
language plpgsql;
-- +goose StatementEnd
Import github.com/pressly/goose
from your own project (see example), register migration functions and run goose command (ie. goose.Up(db *sql.DB, dir string)
).
A sample Go migration 00002_users_add_email.go file looks like:
package migrations
import (
"database/sql"
"github.com/pressly/goose"
)
func init() {
goose.AddMigration(Up, Down)
}
func Up(tx *sql.Tx) error {
_, err := tx.Query("ALTER TABLE users ADD COLUMN email text DEFAULT '' NOT NULL;")
if err != nil {
return err
}
return nil
}
func Down(tx *sql.Tx) error {
_, err := tx.Query("ALTER TABLE users DROP COLUMN email;")
if err != nil {
return err
}
return nil
}
Licensed under MIT License