如何将迁移与可执行文件绑定 [英] How to bind migrations with executable
问题描述
我有一个Go项目,它使用 goose 进行Mysql迁移.我想将迁移绑定到程序包可执行文件,以便该可执行文件可以独立于任何系统进行部署和使用,类似于JAVA项目中的JAR文件.
I have a Go project using goose for Mysql migrations. I would like to bind the migrations to the package executable so that the executable can be deployed and used independently from any system, similar to JAR files in JAVA projects.
Go中是否有等效的工具来实现这一目标?
Is there an equivalent in Go to accomplish that?
推荐答案
如何获取可以迁移数据库并正常工作的单个文件
-
安装
Install
go get -u github.com/pressly/goose/cmd/goose
制作应用.我基于example main.go
并添加run
选项.假设您的项目位于github.com/user/project
:
Make app. I base it on examplemain.go
and add run
option. Suppose your project is located at github.com/user/project
:
package main
import (
"database/sql"
"flag"
"log"
"os"
"github.com/pressly/goose"
// Init DB drivers. -- here I recommend remove unnecessary - but it's up to you
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
_ "github.com/ziutek/mymysql/godrv"
// here our migrations will live -- use your path
_ "github.com/user/project/migrations"
)
var (
flags = flag.NewFlagSet("goose", flag.ExitOnError)
dir = flags.String("dir", ".", "directory with migration files")
)
func main() {
flags.Usage = usage
flags.Parse(os.Args[1:])
args := flags.Args()
//////
if len(args) > 1 && args[0] == "run" {
log.Printf("PROGRAM RUN\n") //
.....
os.Exit(0)
}
if len(args) > 1 && args[0] == "create" {
if err := goose.Run("create", nil, *dir, args[1:]...); err != nil {
log.Fatalf("goose run: %v", err)
}
return
}
if len(args) < 3 {
flags.Usage()
return
}
if args[0] == "-h" || args[0] == "--help" {
flags.Usage()
return
}
driver, dbstring, command := args[0], args[1], args[2]
switch driver {
case "postgres", "mysql", "sqlite3", "redshift":
if err := goose.SetDialect(driver); err != nil {
log.Fatal(err)
}
default:
log.Fatalf("%q driver not supported\n", driver)
}
switch dbstring {
case "":
log.Fatalf("-dbstring=%q not supported\n", dbstring)
default:
}
if driver == "redshift" {
driver = "postgres"
}
db, err := sql.Open(driver, dbstring)
if err != nil {
log.Fatalf("-dbstring=%q: %v\n", dbstring, err)
}
arguments := []string{}
if len(args) > 3 {
arguments = append(arguments, args[3:]...)
}
if err := goose.Run(command, db, *dir, arguments...); err != nil {
log.Fatalf("goose run: %v", err)
}
}
func usage() {
log.Print(usagePrefix)
flags.PrintDefaults()
log.Print(usageCommands)
}
var (
usagePrefix = `Usage: goose [OPTIONS] DRIVER DBSTRING COMMAND
Drivers:
postgres
mysql
sqlite3
redshift
Examples:
goose sqlite3 ./foo.db status
goose sqlite3 ./foo.db create init sql
goose sqlite3 ./foo.db create add_some_column sql
goose sqlite3 ./foo.db create fetch_user_data go
goose sqlite3 ./foo.db up
goose postgres "user=postgres dbname=postgres sslmode=disable" status
goose mysql "user:password@/dbname?parseTime=true" status
goose redshift "postgres://user:password@qwerty.us-east-1.redshift.amazonaws.com:5439/db"
status
Options:
`
usageCommands = `
Commands:
up Migrate the DB to the most recent version available
up-to VERSION Migrate the DB to a specific VERSION
down Roll back the version by 1
down-to VERSION Roll back to a specific VERSION
redo Re-run the latest migration
status Dump the migration status for the current DB
version Print the current version of the database
create NAME [sql|go] Creates new migration file with next version
`
)
为迁移创建文件夹:
Create folder for migrations:
mkdir migrations && cd migrations
创建第一个迁移.我们将使用go
样式的迁移:
Create first migrations. We will use go
-style migrations:
goose mysql "user:password@/dbname?parseTime=true" create init go
您将获得带有Go代码的文件00001_init.go
.迁移作为SQL命令在其中进行.只需根据需要对其进行编辑.
You'll get a file 00001_init.go
with Go code. Migrations are baked in it as SQL-commands. Just edit them as you need.
然后转到主文件夹并构建应用程序:
Then go to the main folder and build the application:
cd ..
go build -v -o myapp *.go
您将获得一个文件myapp
,其中包含所有迁移.要检查将其移动到其他位置,例如到/tmp
文件夹,然后从那里运行:
You'll get a file myapp
with all the migrations baked in it. To check move it to some other place, for example to /tmp
folder, and run from there:
./myapp mysql "user:password@/dbname?parseTime=true" status
运行您的应用程序:
Run your app:
./myapp run
结果
您只有一个文件,可以用作迁移工具,也可以用作运行中的应用程序本身.所有迁移都是内置的.在源代码中,它们存储在子包migrations
中,因此易于编辑.
Result
You have single file which can be used as a migration tool so as a working application itself. All the migration are buil-it. In source code they are stored in a subpackage migrations
- so it's easy to edit.
这篇关于如何将迁移与可执行文件绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!