【问题标题】:Safely perform DB migrations with Go使用 Go 安全地执行数据库迁移
【发布时间】:2021-12-05 01:48:36
【问题描述】:

假设我有一个显示帖子列表的网络应用。帖子结构是:

type Post struct {
    Id         int64 `sql:",primary"`
    Title      string
    Body       string
}

它检索帖子:

    var posts []*Post
    rows, err := db.QueryContext(ctx, "select * from posts;")
    if err != nil {
        return nil, oops.Wrapf(err, "could not get posts")
    }

    defer rows.Close()

    for rows.Next() {
        p := &Post{}
        err := rows.Scan(
            &p.Id,
            &p.Title,
            &p.Body,
        )
        if err != nil {
            return nil, oops.Wrapf(err, "could not scan row")
        }
        posts = append(posts, p)
    }

    return posts, nil

一切正常。现在,我想通过添加一列来更改表架构:

ALTER TABLE posts ADD author varchar(62);

突然,获取帖子的请求导致:

sql: expected 4 destination arguments in Scan, not 3

这是有道理的,因为该表现在有 4 列,而不是检索逻辑规定的 3 列。

然后我可以将结构更新为:

type Post struct {
    Id         int64 `sql:",primary"`
    Title      string
    Body       string
    Author     string
}

和检索逻辑是:

    for rows.Next() {
        p := &Post{}
        err := rows.Scan(
            &p.Id,
            &p.Title,
            &p.Body,
            &p.Author
        )
        if err != nil {
            return nil, oops.Wrapf(err, "could not scan row")
        }
        posts = append(posts, p)
    }

解决了这个问题。但是,这意味着在迁移和逻辑更新 + 部署之间总会有一段停机时间。如何避免停机?

我尝试交换上述更改的顺序,但这不起作用,同样的请求导致:

sql: expected 3 destination arguments in Scan, not 4

(这是有道理的,因为该表当时只有 3 列而不是 4 列);

以及其他导致:

Error 1054: Unknown column 'author' in 'field list'

(这是有道理的,因为此时posts 表还没有author 列)

【问题讨论】:

    标签: mysql go


    【解决方案1】:

    您应该能够通过调整 SQL 查询以返回您想要填充的确切字段来实现您想要的行为。

    SELECT Id , Title , Body FROM posts;

    这样即使你添加另一列Author,查询结果也只包含3个值。

    【讨论】:

    • 我明白了。我希望 mysql 适配器有一种方法可以丢弃多余的列。或者,也许更好的系统将列名映射到结构的字段,可以传递给 QueryContext。使用这种方法,需要为每个查询写下所有列,这增加了大型表的实现开销。另一方面,它使查询更加明确。这似乎是要走的路,谢谢。
    • 看看 gorm:gorm.io 它可能会解决您的许多问题。我从来没有研究过 Gorm 迁移方法的细节,所以我不知道细节。
    猜你喜欢
    • 2011-11-04
    • 2018-12-12
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    相关资源
    最近更新 更多