【问题标题】:Correct Strategy for DB migrations in GoGo 中数据库迁移的正确策略
【发布时间】:2023-03-08 13:34:01
【问题描述】:

我们有一个使用 Postgres 作为后端数据库的 go 应用程序。 我们使用https://github.com/jmoiron/sqlx 与数据库通信。 从表中读取所有行的代码如下:

 rows, err := repo.db.Queryx(ListNodesQuery)
 if err != nil {
    repo.logger.Log("method", "ListNodes", "error", err)
    return nil, err
 }

 r := []*Node{}
 for rows.Next() {
    var n Node
    err = rows.StructScan(&n)
 }

在数据库中添加新列后,代码按预期错误如下

missing destination name type in *Node

因为 db 表有更多的列。更改代码以同时更新结构当然是不可能的。

我发现关闭此错误的一种方法是使用 db.Unsafe 记录的here

还有其他惯用的方法来处理这种情况吗?

【问题讨论】:

  • 您是否使用SELECT * FROM... 上的变体从表中查询?更改此项以明确列出感兴趣的列名。您可以在移动丢弃的数据时节省浪费的数据库和网络资源,并且可以在代码准备好接收来自其他列的值时显式更新查询。
  • 嗯...好点

标签: sql postgresql go sqlx


【解决方案1】:

更改代码以同时更新结构是当然的 不可能。

您可以在代码库中管理数据库架构,并拥有一些应用启动代码,这些代码会自动将数据库迁移到最新的架构版本,以保持代码和数据库同步。

其中一个选项是github.com/golang-migrate

在应用启动时运行此代码以将数据库架构更新到最新版本:

migrate, err := migrate.New("folder to sql scrips", "db connection string")
if err != nil {
    logger.Panic(err)
}
err = migrate.Up()
if err != nil {
    logger.Panic(err)
}

【讨论】:

  • 但是如果我必须回滚,那么我必须再次更改代码以更新结构。
  • 您必须使您的数据库架构和代码架构保持同步。添加/删除列只是该架构演变的众多案例之一。 GO 惯用地想要处理所有错误,包括显式映射。当您想吞下映射不一致时,您是在与语言意图作斗争。
猜你喜欢
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 2018-05-10
  • 2012-09-21
  • 2016-02-28
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多