我有一个Go项目,它使用goose进行Mysql迁移。我想将迁移绑定到程序包可执行文件,以便该可执行文件可以独立于任何系统进行部署和使用,类似于JAVA项目中的JAR文件。
Go可以做到这一点吗?
安装
go get -u github.com/pressly/goose/cmd/goose
制作应用。我基于示例main.go并添加run选项。假设您的项目位于github.com/user/project:
main.go
run
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 ` )
创建用于迁移的文件夹:
mkdir migrations && cd migrations
创建第一个迁移。我们将使用go-style迁移:
go
goose mysql "user:password@/dbname?parseTime=true" create init go
您将获得00001_init.go带有Go代码的文件。迁移作为SQL命令放入其中。只需根据需要对其进行编辑。
00001_init.go
然后转到主文件夹并构建应用程序:
cd ..
go build -v -o myapp *.go
您将获得一个myapp包含所有迁移的文件。要检查将其移动到其他位置,例如移动到/tmp文件夹,然后从那里运行:
myapp
/tmp
./myapp mysql "user:password@/dbname?parseTime=true" status
运行您的应用程序:
./myapp run
您只有一个文件,可用作应用程序本身的迁移工具。所有的迁移都是内置的。在源代码中,它们存储在子包中migrations-易于编辑。
migrations