I like to group my migrations by logical subdirectories. ``` [nicholasduffy@duffn:~/go/src/github.com/pressly/goose/migrations on sql-subdirectories] % tree ✭ . ├── group1 │ └── 20170506073854_table1_create_table.sql └── group2 └── 20170506073920_table2_create_table.sql 2 directories, 2 files ``` It's easy to run migrations by groups if necessary. However, I'd like the ability to run all migrations in all subdirectories at the same time. This PR adds discovery of all SQL files in subdirectories within the `-dir` directory. |
||
---|---|---|
cmd/goose | ||
example | ||
.gitignore | ||
.travis.yml | ||
LICENSE | ||
Makefile | ||
README.md | ||
create.go | ||
dialect.go | ||
down.go | ||
goose.go | ||
migrate.go | ||
migrate_test.go | ||
migration.go | ||
migration_sql.go | ||
migration_sql_test.go | ||
redo.go | ||
status.go | ||
up.go | ||
util.go | ||
version.go |
README.md
goose
Goose is a database migration tool. Manage your database's evolution by creating incremental SQL files or Go functions.
Goals of this fork
github.com/pressly/goose is a fork of bitbucket.org/liamstask/goose with the following changes:
- No config files
- Default goose binary can migrate SQL files only
- Go migrations:
- We dropped building Go migrations on-the-fly from .go source files
- Instead, you can create your own goose binary, import
github.com/pressly/goose
package and run complex Go migrations with your own*sql.DB
connection - Each Go migration function is called with
*sql.Tx
argument - within its own transaction
- The goose pkg is decoupled from the default binary:
- goose pkg doesn't register any SQL drivers anymore
(no driver
panic()
conflict within your codebase!) - goose pkg doesn't have any vendor dependencies anymore
- goose pkg doesn't register any SQL drivers anymore
(no driver
Install
$ go get -u github.com/pressly/goose/cmd/goose
This will install the goose
binary to your $GOPATH/bin
directory.
Usage
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
goose redshift "postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db" create init sql
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
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
up
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
down
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
redo
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
status
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
Note: for MySQL parseTime flag must be enabled.
dbversion
Print the current version of the database:
$ goose dbversion
$ goose: dbversion 002
Migrations
goose supports migrations written in SQL or in Go.
SQL Migrations
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
Go Migrations
- Create your own goose binary, see example
- Import
github.com/pressly/goose
- Register your migration functions
- 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.Exec("UPDATE users SET username='admin' WHERE username='root';")
if err != nil {
return err
}
return nil
}
func Down(tx *sql.Tx) error {
_, err := tx.Exec("UPDATE users SET username='root' WHERE username='admin';")
if err != nil {
return err
}
return nil
}
License
Licensed under MIT License