golang数据库迁移生成工具插件sqlize的使用

Golang数据库迁移生成工具插件sqlize的使用

SQLize是一个强大的迁移生成工具,可以检测两个SQL状态源之间的差异。它通过比较现有的SQL模式和Go模型来简化迁移创建,确保无缝的数据库更新。

特性

  • 支持MySQL、PostgreSQL和SQLite
  • 与流行的Go ORM和迁移工具集成,如gorm、golang-migrate/migrate等
  • 提供高级功能,包括Avro Schema导出(仅MySQL)和ERD图生成(MermaidJS)

默认行为

  • 数据库:mysql(使用sql_builder.WithPostgresql()切换为PostgreSQL等)
  • SQL语法:大写(如"SELECT * FROM user WHERE id = ?")
    • 使用sql_builder.WithSqlLowercase()切换为小写
  • 表命名:单数形式
    • 使用sql_builder.WithPluralTableName()切换为复数形式(添加’s’)
  • 注释生成:使用sql_builder.WithCommentGenerate()

SQL标签选项

type User struct {
    ID        int    `sql:"primary_key"`             // 主键
    Name      string `sql:"column:user_name"`        // 自定义列名
    Email     string `sql:"unique"`                  // 唯一索引
    Age       int    `sql:"default:18"`              // 默认值
    CreatedAt string `sql:"type:TIMESTAMP"`          // 覆盖数据类型
    Status    string `sql:"-"`                       // 忽略字段
    AddressID int    `sql:"foreign_key:address_id;references:id"` // 外键
}

完整示例

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/sunary/sqlize"
)

// 定义模型结构体
type User struct {
	ID        int    `sql:"primary_key"`
	Name      string `sql:"column:user_name"`
	Email     string `sql:"unique"`
	Age       int    `sql:"default:18"`
	CreatedAt string `sql:"type:TIMESTAMP"`
}

// 实现YourModels函数返回模型切片
func YourModels() []interface{} {
	return []interface{}{
		&User{},
	}
}

func main() {
	migrationFolder := "migrations/"
	sqlLatest := sqlize.NewSqlize(sqlize.WithSqlTag("sql"),
		sqlize.WithMigrationFolder(migrationFolder),
		sqlize.WithCommentGenerate())

	ms := YourModels()
	err := sqlLatest.FromObjects(ms...)
	if err != nil {
		log.Fatal("sqlize FromObjects", err)
	}
	sqlVersion := sqlLatest.HashValue()

	sqlMigrated := sqlize.NewSqlize(sqlize.WithMigrationFolder(migrationFolder))
	err = sqlMigrated.FromMigrationFolder()
	if err != nil {
		log.Fatal("sqlize FromMigrationFolder", err)
	}

	sqlLatest.Diff(*sqlMigrated)

	fmt.Println("sql version", sqlVersion)

	fmt.Println("\n\n### migration up")
	migrationUp := sqlLatest.StringUp()
	fmt.Println(migrationUp)

	fmt.Println("\n\n### migration down")
	fmt.Println(sqlLatest.StringDown())

	// 写入迁移文件
	if len(os.Args) > 1 {
		log.Println("write to file", os.Args[1])
		err = sqlLatest.WriteFilesWithVersion(os.Args[1], sqlVersion, false)
		if err != nil {
			log.Fatal("sqlize WriteFilesWithVersion", err)
		}
	}
}

数据类型处理

MySQL数据类型会隐式转换:

TINYINT => tinyint(4)
INT     => int(11)
BIGINT  => bigint(20)

指针值必须在结构体中声明或预定义数据类型:

type Record struct {
	ID        int
	DeletedAt *time.Time `sql:"type:DATETIME"` // 预定义类型
}

// 或使用database/sql支持的struct
type Record struct {
	ID        int
	DeletedAt sql.NullTime
}

SQLize是一个功能强大的工具,可以大大简化Golang项目中的数据库迁移工作。通过比较模型和现有数据库结构,自动生成迁移脚本,确保数据库模式与代码模型保持同步。


更多关于golang数据库迁移生成工具插件sqlize的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

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


SQLize - Golang数据库迁移生成工具

SQLize 是一个用于Golang的数据库迁移工具,它可以帮助你管理数据库架构的变更。下面我将详细介绍SQLize的使用方法和示例代码。

安装SQLize

首先,使用go get命令安装SQLize:

go get -u github.com/sunary/sqlize

基本概念

SQLize 提供了两种主要功能:

  1. 从现有数据库生成迁移文件
  2. 从Golang结构体生成迁移文件

使用示例

1. 从现有数据库生成迁移

package main

import (
	"log"
	
	"github.com/sunary/sqlize"
)

func main() {
	// 创建SQLize实例
	sqlizer := sqlize.NewSqlize(sqlize.WithMigrationFolder("./migrations"))

	// 从数据库生成迁移文件
	err := sqlizer.FromDb("mysql", "user:password@tcp(127.0.0.1:3306)/database_name")
	if err != nil {
		log.Fatal(err)
	}

	// 生成迁移文件
	err = sqlizer.DumpMigrationFiles()
	if err != nil {
		log.Fatal(err)
	}
	
	log.Println("迁移文件生成成功")
}

2. 从Golang结构体生成迁移

package main

import (
	"log"
	
	"github.com/sunary/sqlize"
)

type User struct {
	ID        int64  `sql:"primary_key;auto_increment"`
	Name      string `sql:"type:varchar(100);not null"`
	Email     string `sql:"type:varchar(100);unique;not null"`
	CreatedAt int64  `sql:"type:bigint;not null"`
	UpdatedAt int64  `sql:"type:bigint;not null"`
}

type Post struct {
	ID      int64  `sql:"primary_key;auto_increment"`
	Title   string `sql:"type:varchar(255);not null"`
	Content string `sql:"type:text"`
	UserID  int64  `sql:"type:bigint;not null;index"`
}

func main() {
	// 创建SQLize实例
	sqlizer := sqlize.NewSqlize(
		sqlize.WithMigrationFolder("./migrations"),
		sqlize.WithSqlTag("sql"),
	)

	// 添加模型
	sqlizer.AddModels(
		User{},
		Post{},
	)

	// 生成迁移文件
	err := sqlizer.DumpMigrationFiles()
	if err != nil {
		log.Fatal(err)
	}
	
	log.Println("迁移文件生成成功")
}

3. 自定义迁移文件名

sqlizer := sqlize.NewSqlize(
	sqlize.WithMigrationFolder("./migrations"),
	sqlize.WithMigrationName("create_user_and_post_tables"),
)

4. 使用现有迁移文件

sqlizer := sqlize.NewSqlize(
	sqlize.WithMigrationFolder("./migrations"),
	sqlize.WithMigrationTable("migrations"), // 自定义迁移表名
	sqlize.WithMigrationUp(true),           // 只生成up迁移
	sqlize.WithMigrationDown(false),        // 不生成down迁移
)

高级功能

1. 自定义模板

sqlizer := sqlize.NewSqlize(
	sqlize.WithMigrationFolder("./migrations"),
	sqlize.WithMigrationTemplate(
		sqlize.MigrationTemplate{
			Up:   "/* up migration */\n{{.SqlUp}}",
			Down: "/* down migration */\n{{.SqlDown}}",
		},
	),
)

2. 使用不同的方言

sqlizer := sqlize.NewSqlize(
	sqlize.WithMigrationFolder("./migrations"),
	sqlize.WithDialect(sqlize.Postgres), // 支持MySQL, Postgres, SQLite
)

3. 合并多个模型变更

sqlizer := sqlize.NewSqlize(
	sqlize.WithMigrationFolder("./migrations"),
)

// 第一次添加模型
sqlizer.AddModels(User{})

// 第二次添加模型
sqlizer.AddModels(Post{})

// 生成一个包含所有变更的迁移文件
err := sqlizer.DumpMigrationFiles()

最佳实践

  1. 版本控制:将生成的迁移文件纳入版本控制系统
  2. 小步提交:每次架构变更生成单独的迁移文件
  3. 测试迁移:在生产环境应用前测试迁移脚本
  4. 备份数据:在执行破坏性迁移前备份数据
  5. 文档化:为复杂迁移添加注释说明

注意事项

  1. SQLize 主要用于生成迁移文件,不直接执行迁移
  2. 对于生产环境,建议使用专门的迁移工具(如golang-migrate)来执行迁移
  3. 复杂的数据库变更(如数据迁移)可能需要手动编写迁移脚本

SQLize 是一个强大的工具,可以显著简化Golang项目中的数据库迁移管理。通过结构体定义自动生成迁移文件,可以保持代码和数据库架构的同步,减少手动编写SQL脚本的错误。

回到顶部