goctl model

概述

goctl model 为 goctl 提供的数据库模型代码生成指令,目前支持 MySQL、PostgreSQL、Mongo 的代码生成,MySQL 支持从 sql 文件和数据库连接两种方式生成,PostgreSQL 仅支持从数据库连接生成。

goctl model 指令

  1. $ goctl model --help
  2. Generate model code
  3. Usage:
  4. goctl model [command]
  5. Available Commands:
  6. mongo Generate mongo model
  7. mysql Generate mysql model
  8. pg Generate postgresql model
  9. Flags:
  10. -h, --help help for model
  11. Use "goctl model [command] --help" for more information about a command.

goctl model mongo 指令

Mongo 的生成不同于 MySQL,MySQL 可以从 scheme_information 库中读取到一张表的信息(字段名称,数据类型,索引等), 而 Mongo 是文档型数据库,我们暂时无法从 db 中读取某一条记录来实现字段信息获取,就算有也不一定是完整信息(某些字段可能是 omitempty 修饰,可有可无), 这里采用 type 自己编写+代码生成方式实现。

  1. $ goctl model mongo --help
  2. Generate mongo model
  3. Usage:
  4. goctl model mongo [flags]
  5. Flags:
  6. --branch string The branch of the remote repo, it does work with --remote
  7. -c, --cache Generate code with cache [optional]
  8. -d, --dir string The target dir
  9. -e, --easy Generate code with auto generated CollectionName for easy declare [optional]
  10. -h, --help help for mongo
  11. --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  12. --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  13. The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
  14. --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
  15. -t, --type strings Specified model type name
goctl model - 图1 参数字段goctl model - 图2 参数类型goctl model - 图3 是否必填goctl model - 图4 默认值goctl model - 图5 参数说明
branchstringNO空字符串远程模板所在 git 分支名称,仅当 remote 有值时使用
cachebooleanNOfalse是否生成带缓存的代码
dirstringNO当前工作目录代码输出目录
easybooleanNOfalse是否暴露集合名称变量
homestringNO${HOME}/.goctl本地模板文件目录
remotestringNO空字符串远程模板所在 git 仓库地址,当此字段传值时,优先级高于 home 字段值
stylestringNOgozero输出文件和目录的命名风格格式化符号,详情见文件风格
type[]stringYESnil结构体类型名称

使用示例

以下我们以生成一个 User 结构体为例。

示例 1: 生成带缓存的代码

  1. # 进入用户 Home 目录
  2. $ cd ~
  3. # 创建 demo 目录
  4. $ mkdir demo && cd demo
  5. # 生成 mongo 代码
  6. $ goctl model mongo --type User --dir cache --cache
  7. # 查看目录结构
  8. $ tree
  9. .
  10. └── cache
  11. ├── error.go
  12. ├── usermodel.go
  13. ├── usermodelgen.go
  14. └── usertypes.go
  15. 1 directory, 4 files

查看代码

  • error.go
  • usermodel.go
  • usermodelgen.go
  • usertypes.go
  1. package model
  2. import (
  3. "errors"
  4. "github.com/zeromicro/go-zero/core/stores/mon"
  5. )
  6. var (
  7. ErrNotFound = mon.ErrNotFound
  8. ErrInvalidObjectId = errors.New("invalid objectId")
  9. )
goctl model - 图6tip

用户自定义代码在这个文件编写

  1. package model
  2. import (
  3. "github.com/zeromicro/go-zero/core/stores/cache"
  4. "github.com/zeromicro/go-zero/core/stores/monc"
  5. )
  6. var _ UserModel = (*customUserModel)(nil)
  7. type (
  8. // UserModel is an interface to be customized, add more methods here,
  9. // and implement the added methods in customUserModel.
  10. UserModel interface {
  11. userModel
  12. }
  13. customUserModel struct {
  14. *defaultUserModel
  15. }
  16. )
  17. // NewUserModel returns a model for the mongo.
  18. func NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {
  19. conn := monc.MustNewModel(url, db, collection, c)
  20. return &customUserModel{
  21. defaultUserModel: newDefaultUserModel(conn),
  22. }
  23. }
goctl model - 图7tip

此文件的头部带有 DO NOT EDIT 标识,因此不能修改此文件代码,代码重新生成会覆盖此文件。

  1. // Code generated by goctl. DO NOT EDIT.
  2. package model
  3. import (
  4. "context"
  5. "time"
  6. "github.com/zeromicro/go-zero/core/stores/monc"
  7. "go.mongodb.org/mongo-driver/bson"
  8. "go.mongodb.org/mongo-driver/bson/primitive"
  9. )
  10. var prefixUserCacheKey = "cache:user:"
  11. type userModel interface {
  12. Insert(ctx context.Context, data *User) error
  13. FindOne(ctx context.Context, id string) (*User, error)
  14. Update(ctx context.Context, data *User) error
  15. Delete(ctx context.Context, id string) error
  16. }
  17. type defaultUserModel struct {
  18. conn *monc.Model
  19. }
  20. func newDefaultUserModel(conn *monc.Model) *defaultUserModel {
  21. return &defaultUserModel{conn: conn}
  22. }
  23. func (m *defaultUserModel) Insert(ctx context.Context, data *User) error {
  24. if data.ID.IsZero() {
  25. data.ID = primitive.NewObjectID()
  26. data.CreateAt = time.Now()
  27. data.UpdateAt = time.Now()
  28. }
  29. key := prefixUserCacheKey + data.ID.Hex()
  30. _, err := m.conn.InsertOne(ctx, key, data)
  31. return err
  32. }
  33. func (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {
  34. oid, err := primitive.ObjectIDFromHex(id)
  35. if err != nil {
  36. return nil, ErrInvalidObjectId
  37. }
  38. var data User
  39. key := prefixUserCacheKey + id
  40. err = m.conn.FindOne(ctx, key, &data, bson.M{"_id": oid})
  41. switch err {
  42. case nil:
  43. return &data, nil
  44. case monc.ErrNotFound:
  45. return nil, ErrNotFound
  46. default:
  47. return nil, err
  48. }
  49. }
  50. func (m *defaultUserModel) Update(ctx context.Context, data *User) error {
  51. data.UpdateAt = time.Now()
  52. key := prefixUserCacheKey + data.ID.Hex()
  53. _, err := m.conn.ReplaceOne(ctx, key, bson.M{"_id": data.ID}, data)
  54. return err
  55. }
  56. func (m *defaultUserModel) Delete(ctx context.Context, id string) error {
  57. oid, err := primitive.ObjectIDFromHex(id)
  58. if err != nil {
  59. return ErrInvalidObjectId
  60. }
  61. key := prefixUserCacheKey + id
  62. _, err = m.conn.DeleteOne(ctx, key, bson.M{"_id": oid})
  63. return err
  64. }
  1. package model
  2. import (
  3. "time"
  4. "go.mongodb.org/mongo-driver/bson/primitive"
  5. )
  6. type User struct {
  7. ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
  8. // TODO: Fill your own fields
  9. UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
  10. CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
  11. }

示例 2: 生成不带缓存的代码

  1. # 进入用户 Home 目录
  2. $ cd ~
  3. # 创建 demo 目录
  4. $ mkdir demo && cd demo
  5. # 生成 mongo 代码
  6. $ goctl model mongo --type User --dir nocache
  7. # 查看目录结构
  8. $ tree
  9. .
  10. └── nocache
  11. ├── error.go
  12. ├── usermodel.go
  13. ├── usermodelgen.go
  14. └── usertypes.go
  15. 1 directory, 4 files

查看代码

  • error.go
  • usermodel.go
  • usermodelgen.go
  • usertypes.go
  1. package model
  2. import (
  3. "errors"
  4. "github.com/zeromicro/go-zero/core/stores/mon"
  5. )
  6. var (
  7. ErrNotFound = mon.ErrNotFound
  8. ErrInvalidObjectId = errors.New("invalid objectId")
  9. )
goctl model - 图8tip

用户自定义代码在这个文件编写

  1. package model
  2. import "github.com/zeromicro/go-zero/core/stores/mon"
  3. var _ UserModel = (*customUserModel)(nil)
  4. type (
  5. // UserModel is an interface to be customized, add more methods here,
  6. // and implement the added methods in customUserModel.
  7. UserModel interface {
  8. userModel
  9. }
  10. customUserModel struct {
  11. *defaultUserModel
  12. }
  13. )
  14. // NewUserModel returns a model for the mongo.
  15. func NewUserModel(url, db, collection string) UserModel {
  16. conn := mon.MustNewModel(url, db, collection)
  17. return &customUserModel{
  18. defaultUserModel: newDefaultUserModel(conn),
  19. }
  20. }
goctl model - 图9tip

此文件的头部带有 DO NOT EDIT 标识,因此不能修改此文件代码,代码重新生成会覆盖此文件。

  1. // Code generated by goctl. DO NOT EDIT.
  2. package model
  3. import (
  4. "context"
  5. "time"
  6. "github.com/zeromicro/go-zero/core/stores/mon"
  7. "go.mongodb.org/mongo-driver/bson"
  8. "go.mongodb.org/mongo-driver/bson/primitive"
  9. )
  10. type userModel interface {
  11. Insert(ctx context.Context, data *User) error
  12. FindOne(ctx context.Context, id string) (*User, error)
  13. Update(ctx context.Context, data *User) error
  14. Delete(ctx context.Context, id string) error
  15. }
  16. type defaultUserModel struct {
  17. conn *mon.Model
  18. }
  19. func newDefaultUserModel(conn *mon.Model) *defaultUserModel {
  20. return &defaultUserModel{conn: conn}
  21. }
  22. func (m *defaultUserModel) Insert(ctx context.Context, data *User) error {
  23. if data.ID.IsZero() {
  24. data.ID = primitive.NewObjectID()
  25. data.CreateAt = time.Now()
  26. data.UpdateAt = time.Now()
  27. }
  28. _, err := m.conn.InsertOne(ctx, data)
  29. return err
  30. }
  31. func (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {
  32. oid, err := primitive.ObjectIDFromHex(id)
  33. if err != nil {
  34. return nil, ErrInvalidObjectId
  35. }
  36. var data User
  37. err = m.conn.FindOne(ctx, &data, bson.M{"_id": oid})
  38. switch err {
  39. case nil:
  40. return &data, nil
  41. case mon.ErrNotFound:
  42. return nil, ErrNotFound
  43. default:
  44. return nil, err
  45. }
  46. }
  47. func (m *defaultUserModel) Update(ctx context.Context, data *User) error {
  48. data.UpdateAt = time.Now()
  49. _, err := m.conn.ReplaceOne(ctx, bson.M{"_id": data.ID}, data)
  50. return err
  51. }
  52. func (m *defaultUserModel) Delete(ctx context.Context, id string) error {
  53. oid, err := primitive.ObjectIDFromHex(id)
  54. if err != nil {
  55. return ErrInvalidObjectId
  56. }
  57. _, err = m.conn.DeleteOne(ctx, bson.M{"_id": oid})
  58. return err
  59. }
  1. package model
  2. import (
  3. "time"
  4. "go.mongodb.org/mongo-driver/bson/primitive"
  5. )
  6. type User struct {
  7. ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
  8. // TODO: Fill your own fields
  9. UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
  10. CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
  11. }

新增自定义 model 方法示例

在以上代码生成中可以看出,每张表生成都会有 4 个文件,其中 xxmodel.goxxmodelgen.go 是 model 代码文件,待有 gen.go 文件后缀的 代码一般都会包含 DO NOT EDIT 标识,因此不能在这个文件中添加自定义代码,当用户需要新增或者修改代码时,可以在 xxmodel.go 中进行编辑, 在 xxmodel.go 中我们提供了 customXXXModel 结构体便于开发者进行扩展,这里接着上文生成的无缓存代码作为示例,我们给 user 表新增一个 List 方法。

  1. 编辑 usermodel.go 文件
  2. UserModel 接口中新增方法 List(ctx context.Context, page, limit int) ([]*User, error)
  3. 实现 customUserModel

最终代码如下,灰色底纹部分为新增自定义新增内容

  1. package nocache
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/zeromicro/go-zero/core/stores/sqlx"
  6. )
  7. var _ UserModel = (*customUserModel)(nil)
  8. type (
  9. // UserModel is an interface to be customized, add more methods here,
  10. // and implement the added methods in customUserModel.
  11. UserModel interface {
  12. userModel
  13. List(ctx context.Context, page, limit int) ([]*User, error)
  14. }
  15. customUserModel struct {
  16. *defaultUserModel
  17. }
  18. )
  19. func (c *customUserModel) List(ctx context.Context, page, limit int) ([]*User, error) {
  20. query := fmt.Sprintf("select %s from %s limit ?,?", userRows, c.table)
  21. var resp []*User
  22. err := c.conn.QueryRowsCtx(ctx, &resp, query, (page-1)*limit, limit)
  23. return resp, err
  24. }
  25. // NewUserModel returns a model for the database table.
  26. func NewUserModel(conn sqlx.SqlConn) UserModel {
  27. return &customUserModel{
  28. defaultUserModel: newUserModel(conn),
  29. }
  30. }

忽略字段控制

在 goctl 代码生成逻辑中,生成后的代码会在执行插入或者更新操作时会忽略某些字段的赋值,如 create_timeUpdate_time 等,目前 goctl 默认内置了 create_at, create_time, created_at, update_at, update_time, updated_at) 字段,在某些场景下 开发者可能不需要忽略,或者忽略的字段名称不为这些,开发者可以通过 --ignore-columns (-i) 进行控制,当 --ignore-columns (-i) 传值为空时 则跳过对 column 进行忽略,如果需要指定某些字段,则传具体值即可。

  • 示例 1:跳过 column 忽略
  1. # 必须显示传值为空字符串
  2. $ goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -i ''
  1. ...
  2. var (
  3. studentFieldNames = builder.RawFieldNames(&Student{})
  4. studentRows = strings.Join(studentFieldNames, ",")
  5. studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames), ",")
  6. studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "`type`"), "=?,") + "=?"
  7. )
  8. ...
  • 示例 2:指定某些 column 忽略
  1. ...
  2. var (
  3. studentFieldNames = builder.RawFieldNames(&Student{})
  4. studentRows = strings.Join(studentFieldNames, ",")
  5. studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames, "`column1`", "`column2`"), ",")
  6. studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "`type`", "`column1`", "`column2`"), "=?,") + "=?"
  7. )
  8. ...
  1. # --ignore-columns 支持通过英文逗号分割的字符串来传多个值,也支持指定多个参数来传多个只
  2. $ goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -i 'column1,column2'
  3. # 以上 shell 等同于
  4. $ goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -i 'column1' -i "column2"

goctl model mysql 指令

goctl model mysql 指令用于生成基于 MySQL 的 model 代码,支持生成带缓存和不带缓存的代码。MySQL 代码生成支持从 sql 文件,数据库连接两个来源生成代码。

  1. $ goctl model mysql --help
  2. Generate mysql model
  3. Usage:
  4. goctl model mysql [command]
  5. Available Commands:
  6. datasource Generate model from datasource
  7. ddl Generate mysql model from ddl
  8. Flags:
  9. -h, --help help for mysql
  10. -i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time])
  11. --strict Generate model in strict mode
  12. Use "goctl model mysql [command] --help" for more information about a command.

goctl model mysql datasource 指令

goctl model mysql datasource 指令用于从数据库连接生成 model 代码。

  1. $ goctl model mysql datasource --help
  2. Generate model from datasource
  3. Usage:
  4. goctl model mysql datasource [flags]
  5. Flags:
  6. --branch string The branch of the remote repo, it does work with --remote
  7. -c, --cache Generate code with cache [optional]
  8. -d, --dir string The target dir
  9. -h, --help help for datasource
  10. --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  11. --idea For idea plugin [optional]
  12. --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  13. The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
  14. --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
  15. -t, --table strings The table or table globbing patterns in the database
  16. --url string The data source of database,like "root:password@tcp(127.0.0.1:3306)/database"
  17. Global Flags:
  18. -i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time])
  19. --strict Generate model in strict mode
goctl model - 图10 参数字段goctl model - 图11 参数类型goctl model - 图12 是否必填goctl model - 图13 默认值goctl model - 图14 参数说明
branchstringNO空字符串远程模板所在 git 分支名称,仅当 remote 有值时使用
cachebooleanNOfalse是否生成带缓存的代码
dirstringNO当前工作目录代码输出目录
easybooleanNOfalse是否暴露集合名称变量
homestringNO${HOME}/.goctl本地模板文件目录
remotestringNO空字符串远程模板所在 git 仓库地址,当此字段传值时,优先级高于 home 字段值
stylestringNOgozero输出文件和目录的命名风格格式化符号,详情见文件风格
table[]stringYESnil需要生成代码的表
urlstringYES空字符串数据库连接,格式{{username}}:{{password}}@tcp({{host_port}})/{{db}}
ignore-columns[]stringNOnil需要忽略的字段,插入或者更新时需要忽略的字段,如 create_time
strictbooleanNOfalse是否是严格模式,如果是严格模式下,会对 unsigned 修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为 bigint 类型,如果为unsigned 修饰则对应的 golang 数据类型就为 int64,否则为 uint64,如果 strict 为 false,则不关注 unsigned 修饰

goctl model mysql ddl 指令

goctl model mysql ddl 指令用于从 sql 文件生成 model 代码。

  1. $ goctl model mysql ddl --help
  2. Generate mysql model from ddl
  3. Usage:
  4. goctl model mysql ddl [flags]
  5. Flags:
  6. --branch string The branch of the remote repo, it does work with --remote
  7. -c, --cache Generate code with cache [optional]
  8. --database string The name of database [optional]
  9. -d, --dir string The target dir
  10. -h, --help help for ddl
  11. --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  12. --idea For idea plugin [optional]
  13. --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  14. The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
  15. -s, --src string The path or path globbing patterns of the ddl
  16. --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
  17. Global Flags:
  18. -i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time])
  19. --strict Generate model in strict mode
goctl model - 图15 参数字段goctl model - 图16 参数类型goctl model - 图17 是否必填goctl model - 图18 默认值goctl model - 图19 参数说明
branchstringNO空字符串远程模板所在 git 分支名称,仅当 remote 有值时使用
cachebooleanNOfalse是否生成带缓存的代码
dirstringNO当前工作目录代码输出目录
easybooleanNOfalse是否暴露集合名称变量
homestringNO${HOME}/.goctl本地模板文件目录
remotestringNO空字符串远程模板所在 git 仓库地址,当此字段传值时,优先级高于 home 字段值
srcstringYES空字符串sql 文件路径
stylestringNOgozero输出文件和目录的命名风格格式化符号,详情见文件风格
ignore-columns[]stringNOnil需要忽略的字段,插入或者更新时需要忽略的字段,如 create_time
strictbooleanNOfalse是否是严格模式,如果是严格模式下,会对 unsigned 修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为 bigint 类型,如果为unsigned 修饰则对应的 golang 数据类型就为 int64,否则为 uint64,如果 strict 为 false,则不关注 unsigned 修饰

MySQL 类型映射关系(稳定版本)

  • strict 为 true 时,且 unsigned 修饰
  • strict 不为 true 时
goctl model - 图20 MySQL 类型goctl model - 图21 是否为 null 约束goctl model - 图22 Golang 类型
bitNObyte
tinyintNOuint64
tinyintYESsql.NullInt64
smallintNOuint64
smallintYESsql.NullInt64
mediumintNOuint64
mediumintYESsql.NullInt64
intNOuint64
intYESsql.NullInt64
middleintNOuint64
middleintYESsql.NullInt64
int1NOuint64
int1YESsql.NullInt64
int2NOuint64
int2YESsql.NullInt64
int3NOuint64
int3YESsql.NullInt64
int4NOuint64
int4YESsql.NullInt64
int8NOiunt64
int8YESsql.NullInt64
integerNOuint64
integerYESsql.NullInt64
bigintNOuint64
bigintYESsql.NullInt64
floatNOfloat64
floatYESsql.NullFloat64
float4NOfloat64
float4YESsql.NullFloat64
float8NOfloat64
float8YESsql.NullFloat64
dateNOtime.Time
datetimeNOtime.Time
timstampNOtime.Time
timeNOstring
yearNOint64
charNOstring
varcharNOstring
nvarcharNOstring
ncharNOstring
characterNOstring
longvarcharNOstring
linestringNOstring
multilinestringNOstring
binaryNOstring
varbinaryNOstring
tinytextNOstring
textNOstring
mediumtextNOstring
longtextNOstring
enumNOstring
setNOstring
jsonNOstring
blobNOstring
longblobNOstring
mediumblobNOstring
tinyblobNOstring
boolNObool
blleanNObool
goctl model - 图23 MySQL 类型goctl model - 图24 是否为 null 约束goctl model - 图25 Golang 类型
bitNObyte
tinyintNOint64
tinyintYESsql.NullInt64
smallintNOint64
smallintYESsql.NullInt64
mediumintNOint64
mediumintYESsql.NullInt64
intNOint64
intYESsql.NullInt64
middleintNOint64
middleintYESsql.NullInt64
int1NOint64
int1YESsql.NullInt64
int2NOint64
int2YESsql.NullInt64
int3NOint64
int3YESsql.NullInt64
int4NOint64
int4YESsql.NullInt64
int8NOint64
int8YESsql.NullInt64
integerNOint64
integerYESsql.NullInt64
bigintNOint64
bigintYESsql.NullInt64
floatNOfloat64
floatYESsql.NullFloat64
float4NOfloat64
float4YESsql.NullFloat64
float8NOfloat64
float8YESsql.NullFloat64
dateNOtime.Time
datetimeNOtime.Time
timstampNOtime.Time
timeNOstring
yearNOint64
charNOstring
varcharNOstring
nvarcharNOstring
ncharNOstring
characterNOstring
longvarcharNOstring
linestringNOstring
multilinestringNOstring
binaryNOstring
varbinaryNOstring
tinytextNOstring
textNOstring
mediumtextNOstring
longtextNOstring
enumNOstring
setNOstring
jsonNOstring
blobNOstring
longblobNOstring
mediumblobNOstring
tinyblobNOstring
boolNObool
blleanNObool

goctl model pg 指令

goctl model pg 指令用于从 PostgreSQL 数据库中生成 Go 语言代码。

  1. $ goctl model pg --help
  2. Generate postgresql model
  3. Usage:
  4. goctl model pg [flags]
  5. goctl model pg [command]
  6. Available Commands:
  7. datasource Generate model from datasource
  8. Flags:
  9. -h, --help help for pg
  10. Use "goctl model pg [command] --help" for more information about a command.

goctl model pg datasource 指令

  1. $ goctl model pg datasource --help
  2. Generate model from datasource
  3. Usage:
  4. goctl model pg datasource [flags]
  5. Flags:
  6. --branch string The branch of the remote repo, it does work with --remote
  7. -c, --cache Generate code with cache [optional]
  8. -d, --dir string The target dir
  9. -h, --help help for datasource
  10. --home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  11. --idea For idea plugin [optional]
  12. --remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
  13. The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
  14. -s, --schema string The table schema (default "public")
  15. --strict Generate model in strict mode
  16. --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
  17. -t, --table string The table or table globbing patterns in the database
  18. --url string The data source of database,like "postgres://root:password@127.0.0.1:5432/database?sslmode=disable"
goctl model - 图26 参数字段goctl model - 图27 参数类型goctl model - 图28 是否必填goctl model - 图29 默认值goctl model - 图30 参数说明
branchstringNO空字符串远程模板所在 git 分支名称,仅当 remote 有值时使用
cachebooleanNOfalse是否生成带缓存的代码
dirstringNO当前工作目录代码输出目录
easybooleanNOfalse是否暴露集合名称变量
homestringNO${HOME}/.goctl本地模板文件目录
ideabooleanNOfalse是否为 idea 使用,终端请忽略此字段
remotestringNO空字符串远程模板所在 git 仓库地址,当此字段传值时,优先级高于 home 字段值
strictbooleanNOfalse是否是严格模式,如果是严格模式下,会对 unsigned 修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为 bigint 类型,如果为unsigned 修饰则对应的 golang 数据类型就为 int64,否则为 uint64,如果 strict 为 false,则不关注 unsigned 修饰
stylestringNOgozero输出文件和目录的命名风格格式化符号,详情见文件风格
table[]stringYESnil需要生成代码的表
urlstringYES空字符串数据库连接,格式 postgres://{{username}}:{{password}}@{{host_port}}/{{db}}?sslmode=disable

PostgreSQL 类型映射关系

goctl model - 图31 PostgreSQL 类型goctl model - 图32 Golang 类型
boolbool
_boolpq.BoolArray
booleanbool
tinyintint64
smallintint64
mediumintint64
intint64
int1int64
int2int64
_int2pq.Int64Array
int3int64
int4int64
_int4pq.Int64Array
int8int64
_int8pq.Int64Array
integerint64
_integerpq.Int64Array
bigintint64
floatfloat64
float4float64
_float4pq.Float64Array
float8float64
_float8pq.Float64Array
doublefloat64
decimalfloat64
decfloat64
fixedfloat64
realfloat64
bitbyte
datetime.Time
datetimetime.Time
timestamptime.Time
timestring
yearint64
linestringstring
multilinestringstring
nvarcharstring
ncharstring
charstring
_charpq.StringArray
characterstring
varcharstring
_varcharpq.StringArray
binarystring
byteastring
longvarbinarystring
varbinarystring
tinytextstring
textstring
_textpq.StringArray
mediumtextstring
longtextstring
enumstring
setstring
jsonstring
jsonbstring
blobstring
longblobstring
mediumblobstring
tinyblobstring
ltree[]byte

类型映射自定义

类型映射自定义只有试验版本才能使用,关于如何开启试验版本,请参考 goctl env,关于配置使用请参考 goctl config

示例 1. 修改 decimal 为 decimal.Decimal 类型

  1. 在需要生成 model 的工程中初始化配置
  1. $ goctl config init
  2. goctl.yaml generated in ~/workspace/go-zero/tools/goctl/goctl.yaml
  1. 修改类型映射关系

灰色底纹部分为自定义映射类型。

  1. model:
  2. types_map:
  3. bigint:
  4. null_type: sql.NullInt64
  5. type: int64
  6. unsigned_type: uint64
  7. dec:
  8. null_type: sql.NullFloat64
  9. type: float64
  10. decimal:
  11. null_type: decimal.NullDecimal
  12. pkg: github.com/shopspring/decimal
  13. type: decimal.Decimal
  14. ...

添加 goctl 内置不支持的类型映射

我们在表中有一个 pg 的数据类型为 inet

  1. -- auto-generated definition
  2. create table student
  3. (
  4. id integer not null
  5. constraint student_pk
  6. primary key,
  7. name varchar default ''::character varying not null,
  8. age integer default 0 not null,
  9. description integer not null,
  10. ip_address inet default '0.0.0.0'::inet not null
  11. );
  12. alter table student
  13. owner to postgres;

目前 goctl 内置类型映射不支持的类型,因此 goctl 会报错如下:

  1. $ goctl model pg datasource --url="postgres://postgres:postgrespw@127.0.0.1:55000/postgres?sslmode=disable" --table="user,student" --dir .
  2. Error: unsupported database type: inet

要解决如上问题,在以往 goctl 版本是不支持的,只能给内置类型映射规则添加规则,然后再发版本,但是现在只需要在配置文件中添加一条类型映射规则皆可。

前提要 goctl 版本大于等于 1.6.5,且开始实验性功能

  1. 查看 goctl 版本是否满足条件
  1. $ goctl env
  2. GOCTL_OS=darwin
  3. GOCTL_ARCH=arm64
  4. GOCTL_HOME=/Users/sh00414ml/.goctl
  5. GOCTL_DEBUG=False
  6. GOCTL_CACHE=/Users/sh00414ml/.goctl/cache
  7. GOCTL_EXPERIMENTAL=on # 实验性功能管开如果为 off 则需要开启,开启命令为 goctl env -w GOCTL_EXPERIMENTAL=on
  8. GOCTL_VERSION=1.6.5 # goctl 版本
  9. PROTOC_VERSION=3.19.4
  10. PROTOC_GEN_GO_VERSION=v1.28.0
  11. PROTO_GEN_GO_GRPC_VERSION=1.2.0
  1. 在目标工程项目中初始化 goctl 配置
  1. $ goctl config
  2. goctl.yaml generated in ~/demo/goctl-config/goctl.yaml # 这里以自己电脑输出准,这里仅供参考
  1. 修改 goctl.yaml

增加目标数据类型及映射关系,这里添加一个 inet 的映射,示例如下灰色底纹部分

  1. model:
  2. types_map:
  3. bigint:
  4. null_type: sql.NullInt64
  5. type: int64
  6. unsigned_type: uint64
  7. ...
  8. inet:
  9. null_type: sql.NullString
  10. type: string
  1. 再次生成 model 代码
  1. goctl model pg datasource --url="postgres://postgres:postgrespw@127.0.0.1:55000/postgres?sslmode=disable" --table="user,student" --dir .
  2. Done.