您可以将Go-ograte与GO的嵌入功能一起使用吗?

发布于 2025-01-19 14:48:25 字数 1512 浏览 0 评论 0 原文

我正在尝试使用 Golang-Origrate 将SQL文件迁移到我的PostgreSQL数据库中。我可能做错了,但是当我运行命令迁移时,说找不到方案:

 $ go run ./cmd/  migrate
2022/04/05 16:20:29 no scheme
exit status 1

这是代码:

  // package dbschema contains the database schema, migrations, and seeding data.

    package dbschema
    
    import (
        "context"
        _ "embed" // Calls init function.
        "fmt"
        "log"
    
        "github.com/golang-migrate/migrate/v4"
        "github.com/golang-migrate/migrate/v4/database/postgres"
        "github.com/jmoiron/sqlx"
        "github.com/jonleopard/bootstrap/pkg/sys/database"
        _ "github.com/lib/pq"
    )
    
    var (
        //go:embed sql/000001_schema.up.sql
        schemaDoc string
    
        //go:embed sql/seed.sql
        seedDoc string
    )
    
    // Migrate attempts to bring the schema for db up to date with the migrations
    // defined in this package.
    func Migrate(ctx context.Context, db *sqlx.DB) error {
        if err := database.StatusCheck(ctx, db); err != nil {
            return fmt.Errorf("status check database: %w", err)
        }
    
        driver, err := postgres.WithInstance(db.DB, &postgres.Config{})
        if err != nil {
            return fmt.Errorf("Construct Migrate driver: %w", err)
        }
    
        m, err := migrate.NewWithDatabaseInstance(schemaDoc, "postgres", driver)
        if err != nil {
            log.Fatal(err)
        }
    
        return m.Up()
    }

I'm trying to use golang-migrate to migrate a sql file into my postgresql database. I'm likely doing this wrong, but when I run the command to migrate it says that no scheme is found:

 $ go run ./cmd/  migrate
2022/04/05 16:20:29 no scheme
exit status 1

Here is the code:

  // package dbschema contains the database schema, migrations, and seeding data.

    package dbschema
    
    import (
        "context"
        _ "embed" // Calls init function.
        "fmt"
        "log"
    
        "github.com/golang-migrate/migrate/v4"
        "github.com/golang-migrate/migrate/v4/database/postgres"
        "github.com/jmoiron/sqlx"
        "github.com/jonleopard/bootstrap/pkg/sys/database"
        _ "github.com/lib/pq"
    )
    
    var (
        //go:embed sql/000001_schema.up.sql
        schemaDoc string
    
        //go:embed sql/seed.sql
        seedDoc string
    )
    
    // Migrate attempts to bring the schema for db up to date with the migrations
    // defined in this package.
    func Migrate(ctx context.Context, db *sqlx.DB) error {
        if err := database.StatusCheck(ctx, db); err != nil {
            return fmt.Errorf("status check database: %w", err)
        }
    
        driver, err := postgres.WithInstance(db.DB, &postgres.Config{})
        if err != nil {
            return fmt.Errorf("Construct Migrate driver: %w", err)
        }
    
        m, err := migrate.NewWithDatabaseInstance(schemaDoc, "postgres", driver)
        if err != nil {
            log.Fatal(err)
        }
    
        return m.Up()
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨落□心尘 2025-01-26 14:48:25

NewWithDatabaseInstance 是:

func NewWithDatabaseInstance(sourceURL string, databaseName string, databaseInstance database.Driver) (*Migrate, error)

所以第一个参数是一个 URL,您正在传递脚本本身。 NewWithDatabaseInstance 调用 <一个href="https://github.com/golang-migrate/migrate/blob/331a15d92a86e002ce5043e788cc2ca287ab0cc2/internal/url/url.go#L12" rel="nofollow noreferrer">SchemeFromURL这就是生成您所看到的错误的原因(因为您传递的网址不包含<代码>:)。 URL 由“方案”组成,后跟 :,然后其他信息。

要将 golang-migrate 与 embed 结合使用,请参阅 文档中的示例

//go:embed testdata/migrations/*.sql
var fs embed.FS

func main() {
    d, err := iofs.New(fs, "testdata/migrations")
    if err != nil {
        log.Fatal(err)
    }
    m, err := migrate.NewWithSourceInstance("iofs", d, "postgres://postgres@localhost/postgres?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    err = m.Up()
    if err != nil {
        // ...
    }
    // ...
}

您会注意到,这传递的是一个文件夹(作为 embed.FS)而不是单个文件。这是因为 golang-migrate 旨在应用多个迁移,而不是而不是仅仅针对数据库运行单个脚本。你应该能够使用类似的东西:

//go:embed sql/*.sql
var schemaFs embed.FS
...
d, err := iofs.New(fs, "sql") // Get migrations from sql folder
if err != nil {
    log.Fatal(err)
}
m, err := migrate.NewWithInstance("iofs", d, "postgres", driver)

The definition of NewWithDatabaseInstance is:

func NewWithDatabaseInstance(sourceURL string, databaseName string, databaseInstance database.Driver) (*Migrate, error)

So the first parameter is a URL and you are passing in the script itself. NewWithDatabaseInstance calls SchemeFromURL which is what generates the error you are seeing (because the url you are passing does not contain a :). A URL consists of a "scheme" followed by : and then other info.

To use golang-migrate with embed see the example in the docs:

//go:embed testdata/migrations/*.sql
var fs embed.FS

func main() {
    d, err := iofs.New(fs, "testdata/migrations")
    if err != nil {
        log.Fatal(err)
    }
    m, err := migrate.NewWithSourceInstance("iofs", d, "postgres://postgres@localhost/postgres?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    err = m.Up()
    if err != nil {
        // ...
    }
    // ...
}

You will note that this passes in a folder (as an embed.FS) rather than a single file. This is because golang-migrate is designed to apply multiple migrations rather than just running a single script against the database. You should be able to use something like:

//go:embed sql/*.sql
var schemaFs embed.FS
...
d, err := iofs.New(fs, "sql") // Get migrations from sql folder
if err != nil {
    log.Fatal(err)
}
m, err := migrate.NewWithInstance("iofs", d, "postgres", driver)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文