当前位置: 首页 > 面试题库 >

如何将迁移与可执行文件绑定

姬银龙
2023-03-14
问题内容

我有一个Go项目,它使用goose进行Mysql迁移。我想将迁移绑定到程序包可执行文件,以便该可执行文件可以独立于任何系统进行部署和使用,类似于JAVA项目中的JAR文件。

Go可以做到这一点吗?


问题答案:

如何获得一个可以迁移数据库并工作的文件

  1. 安装

    go get -u github.com/pressly/goose/cmd/goose
    
  2. 制作应用。我基于示例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
    `
    )
  1. 创建用于迁移的文件夹:

    mkdir migrations && cd migrations
    
  2. 创建第一个迁移。我们将使用go-style迁移:

    goose mysql "user:password@/dbname?parseTime=true" create init go
    

您将获得00001_init.go带有Go代码的文件。迁移作为SQL命令放入其中。只需根据需要对其进行编辑。

  1. 然后转到主文件夹并构建应用程序:

    cd ..
    

    go build -v -o myapp *.go

  2. 您将获得一个myapp包含所有迁移的文件。要检查将其移动到其他位置,例如移动到/tmp文件夹,然后从那里运行:

    ./myapp mysql "user:password@/dbname?parseTime=true" status
    
  3. 运行您的应用程序:

    ./myapp run
    

结果

您只有一个文件,可用作应用程序本身的迁移工具。所有的迁移都是内置的。在源代码中,它们存储在子包中migrations-易于编辑。



 类似资料:
  • 在使用可重复迁移时,我观察到一些奇怪的飞行路线行为。文件指出: 在一次迁移运行中,可重复迁移始终在所有挂起的版本化迁移执行完毕后最后应用。 但在我的例子中,可重复迁移(正在重新创建一个DB视图)似乎失败了,因为它是在版本化迁移之前执行的。 迁移前的Flyway信息数据:

  • 我正在使用JPackage(OpenJDK 15.0.1)为Windows制作一个可移植的可执行文件。我尝试了下面的命令,但我双击了生成的exe文件,显示了安装程序窗口。它似乎不是可移植的可执行文件,而只是安装程序。 有什么办法可以用JPackage制作一个不用安装就可以使用的可执行文件?

  • 我制作了一个javafx应用程序表单,我得到了一个可执行的jar作为输出。现在,我的javafx应用程序依赖于两个第三方JAR,比如commons。伊奥。2.4.罐子 目前,为了运行我的应用程序,我必须像这样将这些依赖jar保存在可执行jar的类路径中 但我希望所有依赖的jar都捆绑在我的可执行jar中。 因为javafx使用ant构建,所以我尝试使用 但是在捆绑了所有依赖的jar之后,我没有得到

  • 在Spring Boot 1.5.x中,我通过扩展创建了一个执行器endpoint。但这个类在Spring Boot2.x中不再存在。 我如何升级下面的类?

  • 我有一个使用Flyway迁移的Spring Boot应用程序。一切正常,从: Intellij内部 从MacBook上的终端 使用“fine”,我的意思是找到迁移文件,这些文件被放置在src/main/resources中,并最终被放置在Spring Boot可执行JAR中。 但是,当我在CentOS6.8上从命令行运行jar时,Flyway无法找到迁移文件。 使用Java8。

  • 我目前正在学习nestjs。当我遇到typeorm时,它是生成迁移的脚本,它在一个文件中创建每个表。现在在我的工作场所,我们在这里使用快速Js,他们为每个表创建迁移文件。结构看起来或多或少像下面: 虽然我更喜欢nestjs方法,但我想知道哪种方法是创建迁移文件的最佳方法。如果更好的方法是上面的例子,那么优点和缺点是什么。任何帮助都将不胜感激,谢谢。 编辑:长话短说,表迁移方法哪个更好,每个表一个文