我有一个使用goose进行Mysql迁移的Golang项目。我想将迁移绑定到包可执行文件,以便可以独立于任何系统部署和使用可执行文件,类似于JAVA项目中的JAR文件。
Golang中是否有相同的功能来完成它?
答案 0 :(得分:1)
如果您使用Docker,您可以将文件夹放入图像。
如果不是https://github.com/rakyll/statik或https://github.com/jteeuwen/go-bindata等项目可以提供帮助。
答案 1 :(得分:1)
如果您已经在使用Goose,则可以选择在Go中编写迁移而不是SQL。根据Goose repo中的Go migrations example,当您在此处构建goose
二进制文件时,它会将所有*.go
二进制文件捆绑到二进制文件中。
这是我构建示例后删除除二进制本身之外的所有文件的输出。嵌入了基于Go的迁移:
2017/10/31 11:22:31 Applied At Migration
2017/10/31 11:22:31 =======================================
2017/10/31 11:22:31 Mon Jun 19 21:56:00 2017 -- 00002_rename_root.go
如果您希望使用基于SQL的迁移但又不想承担其他依赖项,则可以将基于SQL的迁移嵌入到*.go
文件中作为字符串常量,然后,从go-migrations
示例开始,将init阶段添加到main.go
,然后将其写入当前目录,然后再继续。
答案 2 :(得分:1)
安装
go get -u github.com/pressly/goose/cmd/goose
制作应用。我将其基于示例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
式样迁移:
goose mysql "user:password@/dbname?parseTime=true" create init go
您将获得带有Go代码的文件00001_init.go
。迁移作为SQL命令在其中进行烘焙。只需根据需要进行编辑即可。
然后转到主文件夹并构建应用程序:
cd ..
go build -v -o myapp *.go
您将获得一个文件myapp
,其中包含所有迁移。要检查将其移动到其他位置,例如移动到/tmp
文件夹,然后从那里运行:
./myapp mysql "user:password@/dbname?parseTime=true" status
运行您的应用:
./myapp run
您拥有单个文件,可用作迁移工具,也可用作工作应用程序。所有迁移都是建立的。在源代码中,它们存储在子包migrations
中 - 因此很容易编辑。