250 lines
8.3 KiB
Markdown
250 lines
8.3 KiB
Markdown
[![Go Report Card](https://goreportcard.com/badge/git.webz.asia/go-migration/gorm-goose)](https://goreportcard.com/report/git.webz.asia/go-migration/gorm-goose)
|
|
[![Actions Status](https://git.webz.asia/go-migration/gorm-goose/v2/workflows/Go/badge.svg)](https://git.webz.asia/go-migration/gorm-goose/v2/actions)
|
|
[![Build Status](https://travis-ci.org/go-migration/gorm-goose.svg?branch=master)](https://travis-ci.org/go-migration/gorm-goose)
|
|
[![codecov](https://codecov.io/gh/go-migration/gorm-goose/branch/master/graph/badge.svg)](https://codecov.io/gh/go-migration/gorm-goose)
|
|
|
|
# gorm-goose
|
|
|
|
This is a fork of (https://github.com/Altoros/gorm-goose)[https://github.com/Altoros/gorm-goose] which is also fork of [https://bitbucket.org/liamstask/goose](https://bitbucket.org/liamstask/goose) for [gorm](https://github.com/jinzhu/gorm).
|
|
|
|
gorm-goose is a database migration tool for [gorm](https://github.com/jinzhu/gorm).
|
|
Currently, available drivers are: "postgres", "mysql", or "sqlite3".
|
|
|
|
You can manage your database's evolution by creating incremental SQL or Go scripts.
|
|
|
|
## Install
|
|
|
|
$ go get git.webz.asia/go-migration/gorm-goose/v2/cmd/gorm-goose
|
|
|
|
This will install the `gorm-goose` binary to your `$GOPATH/bin` directory.
|
|
|
|
You can also build gorm-goose into your own applications by importing `git.webz.asia/go-migration/gorm-goose/v2/lib/gorm-goose`.
|
|
|
|
## Usage
|
|
|
|
gorm-goose provides several commands to help manage your database schema.
|
|
|
|
### create
|
|
|
|
Create a new Go migration.
|
|
|
|
$ gorm-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:
|
|
|
|
$ gorm-goose create AddSomeColumns sql
|
|
$ goose: created db/migrations/20130106093224_AddSomeColumns.sql
|
|
|
|
### up
|
|
|
|
Apply all available migrations.
|
|
|
|
$ gorm-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
|
|
|
|
#### option: pgschema
|
|
|
|
Use the `pgschema` flag with the `up` command specify a postgres schema.
|
|
|
|
$ gorm-goose -pgschema=my_schema_name 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.
|
|
|
|
$ gorm-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.
|
|
|
|
$ gorm-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:
|
|
|
|
$ gorm-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
|
|
|
|
### dbversion
|
|
|
|
Print the current version of the database:
|
|
|
|
$ gorm-goose dbversion
|
|
$ goose: dbversion 002
|
|
|
|
|
|
`gorm-goose -h` provides more detailed info on each command.
|
|
|
|
|
|
## Migrations
|
|
|
|
gorm-goose supports migrations written in SQL or in Go - see the `gorm-goose create` command above for details on how to generate them.
|
|
|
|
### SQL Migrations
|
|
|
|
A sample SQL migration looks like:
|
|
|
|
```sql
|
|
-- +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:
|
|
|
|
```sql
|
|
-- +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
|
|
|
|
A sample Go migration looks like:
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/jinzhu/gorm"
|
|
)
|
|
|
|
func Up_20130106222315(txn *gorm.DB) {
|
|
fmt.Println("Hello from migration 20130106222315 Up!")
|
|
}
|
|
|
|
func Down_20130106222315(txn *gorm.DB) {
|
|
fmt.Println("Hello from migration 20130106222315 Down!")
|
|
}
|
|
|
|
```
|
|
|
|
`Up_20130106222315()` will be executed as part of a forward migration, and `Down_20130106222315()` will be executed as part of a rollback.
|
|
|
|
The numeric portion of the function name (`20130106222315`) must be the leading portion of migration's filename, such as `20130106222315_descriptive_name.go`. `gorm-goose create` does this by default.
|
|
|
|
A transaction is provided, rather than the DB instance directly, since gorm-goose also needs to record the schema version within the same transaction. Each migration should run as a single transaction to ensure DB integrity, so it's good practice anyway.
|
|
|
|
|
|
## Configuration
|
|
|
|
gorm-goose expects you to maintain a folder (typically called "db"), which contains the following:
|
|
|
|
* a `dbconf.yml` file that describes the database configurations you'd like to use
|
|
* a folder called "migrations" which contains `.sql` and/or `.go` scripts that implement your migrations
|
|
|
|
You may use the `-path` option to specify an alternate location for the folder containing your config and migrations.
|
|
|
|
A sample `dbconf.yml` looks like
|
|
|
|
```yml
|
|
development:
|
|
driver: postgres
|
|
open: user=liam dbname=tester sslmode=disable
|
|
```
|
|
|
|
Here, `development` specifies the name of the environment, and the `driver` and `open` elements are passed directly to database/sql to access the specified database.
|
|
|
|
You may include as many environments as you like, and you can use the `-env` command line option to specify which one to use. gorm-goose defaults to using an environment called `development`.
|
|
|
|
gorm-goose will expand environment variables in the `open` element. For an example, see the Heroku section below.
|
|
|
|
### Using goose with Heroku
|
|
|
|
These instructions assume that you're using [Keith Rarick's Heroku Go buildpack](https://github.com/kr/heroku-buildpack-go). First, add a file to your project called (e.g.) `install_goose.go` to trigger building of the goose executable during deployment, with these contents:
|
|
|
|
```go
|
|
// use build constraints to work around http://code.google.com/p/go/issues/detail?id=4210
|
|
// +build heroku
|
|
|
|
// note: need at least one blank line after build constraint
|
|
package main
|
|
|
|
import _ "git.webz.asia/go-migration/gorm-goose/v2/cmd/gorm-goose"
|
|
```
|
|
|
|
[Set up your Heroku database(s) as usual.](https://devcenter.heroku.com/articles/heroku-postgresql)
|
|
|
|
Then make use of environment variable expansion in your `dbconf.yml`:
|
|
|
|
```yml
|
|
production:
|
|
driver: postgres
|
|
open: $DATABASE_URL
|
|
```
|
|
|
|
To run gorm-goose in production, use `heroku run`:
|
|
|
|
heroku run gorm-goose -env production up
|
|
|
|
## License
|
|
|
|
Copyright 2020 Alex aka mailoman <alex@webz.asia>
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|