使用 Golang 迁移
什么是迁移?
迁移被广泛用于维护数据库结构的版本控制,它是保持数据库井然有序的一个非常有用的解决方案。
假设您有一个用户表,并且需要在该表中插入一个新字段,如果没有迁移,您将需要手动运行 SQL,例如:
  ALTER TABLE "users" ADD COLUMN "phone" VARCHAR(255) NULL;
现在,每次您需要重新创建users表时,您都需要记住创建此字段,除非您更改users表的原始创建,但随着表和应用程序的增长,这变得不可行,因此使用迁移是一个很好的选择。
迁徙
迁移的工作方式相对简单,我们通常有一个up文件和另一个down文件,一些 ORM(如PrismaORM)只创建 1 个文件,在该up文件中我们创建将创建或更改数据库的 SQL,在该down文件中我们创建撤消更改的 SQL。
有什么好处?
现在有了这些文件,我们维护了数据库更改的历史记录,每个更改都有其up文件down,现在如果我们需要创建表,我们运行所有up文件,一切都会创建,如果需要恢复,只需运行down。
Go 中的迁移
Go 本身不支持使用迁移,但我们可以使用具有此功能的 ORM,例如社区最常用的 GORM,但我们可以在不使用 ORM 的情况下使用迁移,为此我们将使用golang -migrate包。
Golang 迁移包
golang-migrate包是最适合此用途的,我们已经拥有管理迁移所需的一切,并且它几乎支持所有数据库,因此在我们的示例中我们将使用 PostgreSQL。
示例项目
我之前创建了一个简单的项目,但我会快速解释它,因为重点是使用迁移。
我们将有这个结构,非常简单,示例的代码应该在main.go:
  package main
  import (
    "database/sql"
    "fmt"
    "log"
    "os"
    "github.com/joho/godotenv"
    _ "github.com/lib/pq"
  )
  func main() {
    // load .env file
    godotenv.Load()
    postgresURI := os.Getenv("DATABASE_URL")
    db, err := sql.Open("postgres", postgresURI)
    if err != nil {
      log.Panic(err)
    }
    err = db.Ping()
    if err != nil {
      db.Close()
      log.Panic(err)
    }
    fmt.Println("Connected to database")
    // keep the program running
    select {}
  }
使用 golang-migrate
我们需要安装 golang-migrate 包的 CLI,查看如何安装这里,运行命令:
  migrate -version
如果输出类似于:
  v4.16.2
好的,继续!下一步是使用以下命令创建我们的第一个迁移:
  migrate create -ext=sql -dir=internal/database/migrations -seq init
- ext:定义扩展,我们使用sql。
- dir:这是我们将创建迁移的目录。
- seq:定义迁移文件名的序列,我们将使用数字,也可以使用时间戳。
这样,您会注意到在数据库文件夹内创建了一个名为migrations的文件夹。
文件up和down文件按顺序创建,因为第一个是000001,如果再次运行该migrate create命令,它将创建迁移000002。现在让我们创建 SQL 并运行迁移:
在该up文件中,我们将创建下表:
  CREATE TABLE users (
    id VARCHAR(36) NOT NULL PRIMARY KEY,
    first_name VARCHAR(255) NOT NULL,
    last_name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP(3) NOT NULL
  );
现在down我们将在文件中删除表格:
  DROP TABLE IF EXISTS users;
准备好 SQL 后,我们就可以运行up迁移了,不要忘记确保数据库正在运行,为此我在项目中留下了一个 docker compose 文件来运行 PostgreSQL 镜像。
  migrate -path=internal/database/migrations -database "postgresql://golang_migrate:golang_migrate@localhost:5432/golang_migrate?sslmode=disable" -verbose up
- path:定义我们的迁移位置。
- database:数据库连接url。
- -verbose:仅显示所有运行。
如果我们访问PgAdmin或Beekeeper之类的客户端,或者通过 bash 访问其容器并通过 CLI 检查,我们可以看到该表已成功创建:
现在我们可以运行了down,它是完全相同的命令,但是从 更改up为down:
  migrate -path=internal/database/migrations -database "postgresql://golang_migrate:golang_migrate@localhost:5432/golang_migrate?sslmode=disable" -verbose down
这样,表格就被删除了。
添加更多字段
现在让我们看看如果需要向表中添加另一个字段会是什么样子users,如果没有迁移,我们就必须直接更改原始表,但是有了迁移,我们就不需要了,让我们创建另一个迁移:
  migrate create -ext=sql -dir=internal/database/migrations -seq init
它将创建顺序为000002up的迁移,让我们添加字段:downphone
up:
  ALTER TABLE "users" ADD COLUMN "phone" VARCHAR(255) NULL;
down:
  ALTER TABLE "users" DROP COLUMN "phone";
再次运行时:
  migrate -path=internal/database/migrations -database "postgresql://golang_migrate:golang_migrate@localhost:5432/golang_migrate?sslmode=disable" -verbose up
我们的phone字段已添加到用户表中,但是如果我只想down在添加该字段的迁移中添加它,该怎么办phone?可以,只需使用相同的命令,传递值 1,这意味着您要撤消上一次迁移:
  migrate -path=internal/database/migrations -database "postgresql://golang_migrate:golang_migrate@localhost:5432/golang_migrate?sslmode=disable" -verbose down 1
该phone字段已被删除。
让 CLI 更易于使用
如您所见,golang-migrate 命令使用起来可能有点累,我们可以通过使用文件makefile使其更容易。
  include .env
  create_migration:
    migrate create -ext=sql -dir=internal/database/migrations -seq init
  migrate_up:
    migrate -path=internal/database/migrations -database "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable" -verbose up
  migrate_down:
    migrate -path=internal/database/migrations -database "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable" -verbose down
  .PHONY: create_migration migrate_up migrate_down
我们创建运行migrate命令的快捷方式,我们需要使用包含我们的环境include .env,然后我们创建命令:
- create_migration:创建我们的迁移文件。
- migrate_up:运行迁移- up。
- migrate_down:运行迁移- down。
- PHONY:它将执行一个命令,makefile 可能会尝试获取一个文件,- migrate_up例如,如果存在具有该名称的文件。
有了它,只需使用以下命令:
  make create_migration
我们将创建迁移文件,这适用于创建的其他快捷方式。
最后的考虑
在本文中,我们了解了如何使用迁移,以及它对于维护变更历史记录和方便数据库维护的重要性。但值得一提的是,错误地使用迁移可能会导致数据库中的数据丢失,因此了解迁移的工作原理以及 ORM 或编程语言如何处理迁移非常重要。
避免删除迁移,如果使用不当,它们可能会成为一场噩梦。
存储库链接
存储库项目
请参阅我博客上的这篇文章
鏂囩珷鏉ユ簮锛�https://dev.to/wiliamvj/using-migrations-with-golang-3449 后端开发教程 - Java、Spring Boot 实战 - msg200.com
            后端开发教程 - Java、Spring Boot 实战 - msg200.com
          

