golang轻量级框架无关数据库迁移工具插件dbmate的使用

Golang轻量级框架无关数据库迁移工具插件dbmate的使用

概述

Dbmate是一个数据库迁移工具,可以帮助你在多个开发者和生产服务器之间保持数据库模式同步。它是一个独立的命令行工具,可以与Go、Node.js、Python、Ruby、PHP、Rust、C++或任何其他语言或框架一起使用。

主要特性

  • 支持MySQL、PostgreSQL、SQLite和ClickHouse
  • 使用纯SQL编写模式迁移
  • 迁移文件使用时间戳版本,避免多开发者之间的版本号冲突
  • 迁移在事务中原子性运行
  • 支持创建和删除数据库(在开发/测试中很有用)
  • 支持保存schema.sql文件,方便在git中比较模式变更
  • 数据库连接URL通过环境变量定义(默认为DATABASE_URL),或通过命令行指定
  • 内置支持从.env文件读取环境变量
  • 易于分发,单个自包含二进制文件

安装

macOS

使用Homebrew安装:

brew install dbmate
dbmate --help

Linux

直接安装二进制文件:

sudo curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
sudo chmod +x /usr/local/bin/dbmate
/usr/local/bin/dbmate --help

Windows

使用Scoop安装:

scoop install dbmate
dbmate --help

Docker

Docker镜像发布到GitHub Container Registry:

docker run --rm -it --network=host ghcr.io/amacneil/dbmate --help

基本命令

dbmate --help    # 打印帮助信息
dbmate new       # 生成新的迁移文件
dbmate up        # 创建数据库(如果不存在)并运行所有待处理的迁移
dbmate create    # 创建数据库
dbmate drop      # 删除数据库
dbmate migrate   # 运行所有待处理的迁移
dbmate rollback  # 回滚最近的迁移
dbmate down      # rollback的别名
dbmate status    # 显示所有迁移的状态
dbmate dump      # 导出数据库schema.sql文件
dbmate load      # 加载schema.sql文件到数据库
dbmate wait      # 等待数据库服务器可用

使用示例

1. 创建迁移文件

dbmate new create_users_table

这将创建一个迁移文件,如db/migrations/20230101000000_create_users_table.sql

-- migrate:up
create table users (
  id integer,
  name varchar(255),
  email varchar(255) not null
);

-- migrate:down
drop table users;

2. 运行迁移

dbmate up

输出示例:

Creating: myapp_development
Applying: 20230101000000_create_users_table.sql
Applied: 20230101000000_create_users_table.sql in 123µs
Writing: ./db/schema.sql

3. 回滚迁移

dbmate rollback

输出示例:

Rolling back: 20230101000000_create_users_table.sql
Rolled back: 20230101000000_create_users_table.sql in 123µs
Writing: ./db/schema.sql

4. 查看迁移状态

dbmate status

数据库连接配置

默认情况下,dbmate使用DATABASE_URL环境变量来定位数据库。可以在.env文件中设置:

$ cat .env
DATABASE_URL="postgres://postgres@127.0.0.1:5432/myapp_development?sslmode=disable"

不同数据库的连接字符串格式

PostgreSQL

DATABASE_URL="postgres://username:password@127.0.0.1:5432/database_name?sslmode=disable"

MySQL

DATABASE_URL="mysql://username:password@127.0.0.1:3306/database_name"

SQLite

DATABASE_URL="sqlite:db/database.sqlite3"

ClickHouse

DATABASE_URL="clickhouse://username:password@127.0.0.1:9000/database_name"

在Go项目中使用dbmate作为库

package main

import (
	"net/url"

	"github.com/amacneil/dbmate/v2/pkg/dbmate"
	_ "github.com/amacneil/dbmate/v2/pkg/driver/postgres"
)

func main() {
	u, _ := url.Parse("postgres://postgres@127.0.0.1:5432/myapp_development?sslmode=disable")
	db := dbmate.New(u)

	err := db.CreateAndMigrate()
	if err != nil {
		panic(err)
	}
}

嵌入迁移文件

package main

import (
	"embed"
	"net/url"

	"github.com/amacneil/dbmate/v2/pkg/dbmate"
	_ "github.com/amacneil/dbmate/v2/pkg/driver/postgres"
)

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

func main() {
	u, _ := url.Parse("postgres://postgres@127.0.0.1:5432/myapp_development?sslmode=disable")
	db := dbmate.New(u)
	db.FS = fs

	err := db.CreateAndMigrate()
	if err != nil {
		panic(err)
	}
}

高级用法

禁用事务

某些操作(如PostgreSQL中的ALTER TYPE)不能在事务中运行:

-- migrate:up transaction:false
ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';

等待数据库可用

dbmate wait

或者与其他命令一起使用:

dbmate --wait up

自定义超时时间

dbmate --wait-timeout=5s wait

总结

Dbmate是一个简单易用的数据库迁移工具,具有以下优势:

  1. 轻量级且独立,不依赖特定框架
  2. 使用纯SQL编写迁移,易于理解和维护
  3. 支持多种数据库
  4. 提供创建/删除数据库、迁移、回滚等完整功能
  5. 可以轻松集成到Go项目中作为库使用

通过合理使用dbmate,可以有效地管理数据库模式的变更,确保开发、测试和生产环境的一致性。


更多关于golang轻量级框架无关数据库迁移工具插件dbmate的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级框架无关数据库迁移工具插件dbmate的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用dbmate进行Golang数据库迁移

dbmate是一个轻量级、框架无关的数据库迁移工具,支持多种数据库系统。它简单易用,不需要依赖特定框架,非常适合Golang项目中使用。

安装dbmate

可以通过以下方式安装dbmate:

# 使用Homebrew (macOS/Linux)
brew install dbmate

# 使用Go安装
go install github.com/amacneil/dbmate/v2@latest

# 直接下载二进制
curl -fsSL https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64 -o dbmate
chmod +x dbmate

基本使用

1. 初始化项目

dbmate init

这会创建一个db目录和.env文件。

2. 配置数据库连接

编辑.env文件:

DATABASE_URL="postgres://username:password@localhost:5432/database_name?sslmode=disable"

支持多种数据库:

  • PostgreSQL: postgres://...
  • MySQL: mysql://...
  • SQLite: sqlite:database.sqlite3

3. 创建迁移文件

dbmate new create_users_table

这会生成一个类似db/20240101000000_create_users_table.sql的文件。

4. 编写迁移SQL

编辑生成的SQL文件:

-- migrate:up
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- migrate:down
DROP TABLE users;

5. 运行迁移

dbmate up

在Golang项目中使用

虽然dbmate本身是命令行工具,但可以在Golang项目中集成它的功能:

1. 使用exec包运行dbmate命令

package main

import (
	"log"
	"os"
	"os/exec"
)

func main() {
	// 设置环境变量
	os.Setenv("DATABASE_URL", "postgres://user:pass@localhost:5432/mydb?sslmode=disable")

	// 运行dbmate up
	cmd := exec.Command("dbmate", "up")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		log.Fatalf("dbmate up failed: %v", err)
	}

	log.Println("Database migrations applied successfully")
}

2. 使用Go API (实验性)

dbmate也提供了Go API:

package main

import (
	"log"
	"os"

	"github.com/amacneil/dbmate/v2/pkg/dbmate"
	_ "github.com/amacneil/dbmate/v2/pkg/driver/postgres"
)

func main() {
	// 初始化dbmate
	db := dbmate.New(os.Getenv("DATABASE_URL"))
	db.MigrationsDir = []string{"./db"}

	// 创建迁移
	// err := db.CreateMigration("create_users_table")

	// 执行迁移
	err := db.Migrate()
	if err != nil {
		log.Fatalf("Migration failed: %v", err)
	}

	log.Println("Migrations applied successfully")
}

常用命令

命令 描述
dbmate new NAME 创建新的迁移文件
dbmate up 运行所有待处理的迁移
dbmate down 回滚最近一次迁移
dbmate rollback 等同于down
dbmate status 显示迁移状态
dbmate dump 导出数据库结构
dbmate wait 等待数据库可用

高级功能

1. 使用自定义迁移目录

dbmate --migrations-dir=./migrations up

或者在Go代码中:

db.MigrationsDir = []string{"./migrations"}

2. 使用schema文件

dbmate dump

这会创建一个schema.sql文件,包含当前数据库结构。

3. 等待数据库可用

在Docker环境中特别有用:

dbmate wait

4. 使用不同的.env文件

dbmate --env-file=.env.test up

最佳实践

  1. 每个迁移文件应该只做一件事
  2. 总是编写down迁移以便回滚
  3. 将迁移文件纳入版本控制
  4. 在生产环境运行迁移前,先在测试环境验证
  5. 考虑在CI/CD流程中加入迁移步骤

dbmate是一个简单但功能强大的工具,可以帮助你在Golang项目中轻松管理数据库迁移,而不需要引入重型ORM或框架。

回到顶部