前言

最近在用 Golang 重构一个 Python web 项目,之前后端主要的技术栈是 flask+sqlalchemy+celery,综合现有情况, 我选择了使用 gin+gorm+cron 来做相应替换。但重构过程中发现某些功能在 Golang 生态中并不是那么完善,需要自己进行二次开发, 主要是在 ORM 和定时任务这两块。

ORM

Model 生成

Model 生成有比较完善的工具 gen,通过读数据库schema信息直接生成 Struct。一些常用的配置:

  • WithDataTypeMap 用来做类型映射,如bigint 映射成 int
  • WithJSONTagNameStrategy 用来设置 json tag 生成规则,如 password 字段的 tag 设置成-
  • WithImportPkgPath 用来添加第三包引入,如使用了 decimal 类型的话需要引入decimal
  • gen.WithMethod option 来添加自定义方法

Migration

Golang 中比较广泛使用的三个方案有 golang-migrategooseatlas,但大多需要自己手写 SQL, 远没有 Python 中的 alembic 简单好用。后面查阅了一番文档,atlas 还是可以通过 gorm Model 来生成 migration SQL,只是步骤复杂了点。

生成 migration SQL

  1. 使用 gorm db.AutoMigrate 方法将所有 Model生成到一个临时的数据库中
  2. 使用 atlas migrate diff 对比 migrations 文件夹和临时数据库表结构的差别从而生成 migration SQL

升级

使用 atlas migrate apply 1 命令升级一个版本

降级

  1. 找到上一个版本号prevVersion
  2. 使用atlas schema apply 命令, 其中 --to 参数中指定 version=${prevVersion}
  3. 使用atlas migrate set ${prevVersion}来设置当前版本

定时任务

cron 代码简洁明了, cron.Recovercron.SkipIfStillRunning 插件功能也很实用。

REST 接口

基于使用场景我做了一下封装,添加了一些 REST 接口:

  1. 调用 cron.Removecron.Add 来实现动态停止和启动 Job,
  2. 获取已注册 Job 列表
  3. 单次运行 Job

Job 扩展

默认的 Job只有 EntryID 信息,所以做了如下扩展。

1
2
3
4
5
6
7
type Job interface {
	Run()
	ID() int
	Name() string
	Schedule() string
	Remark() string
}

相关链接