goctl model
goctl model
概述
goctl model 为 goctl 提供的数据库模型代码生成指令,目前支持 MySQL、PostgreSQL、Mongo 的代码生成,MySQL 支持从 sql 文件和数据库连接两种方式生成,PostgreSQL 仅支持从数据库连接生成。
goctl model 指令
$ goctl model --help
Generate model code
Usage:
goctl model [command]
Available Commands:
mongo Generate mongo model
mysql Generate mysql model
pg Generate postgresql model
Flags:
-h, --help help for model
Use "goctl model [command] --help" for more information about a command.
goctl model mongo 指令
Mongo 的生成不同于 MySQL,MySQL 可以从 scheme_information 库中读取到一张表的信息(字段名称,数据类型,索引等), 而 Mongo 是文档型数据库,我们暂时无法从 db 中读取某一条记录来实现字段信息获取,就算有也不一定是完整信息(某些字段可能是 omitempty 修饰,可有可无), 这里采用 type 自己编写+代码生成方式实现。
$ goctl model mongo --help
Generate mongo model
Usage:
goctl model mongo [flags]
Flags:
--branch string The branch of the remote repo, it does work with --remote
-c, --cache Generate code with cache [optional]
-d, --dir string The target dir
-e, --easy Generate code with auto generated CollectionName for easy declare [optional]
-h, --help help for mongo
--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
--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
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
--style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
-t, --type strings Specified model type name
``` 参数字段| 参数类型| 是否必填| 默认值| 参数说明
---|---|---|---|---
branch| string| NO| 空字符串| 远程模板所在 git 分支名称,仅当 `remote` 有值时使用
cache| boolean| NO| `false`| 是否生成带缓存的代码
dir| string| NO| 当前工作目录| 代码输出目录
easy| boolean| NO| `false`| 是否暴露集合名称变量
home| string| NO| `${HOME}/.goctl`| 本地模板文件目录
remote| string| NO| 空字符串| 远程模板所在 git 仓库地址,当此字段传值时,优先级高于 `home` 字段值
style| string| NO| `gozero`| 输出文件和目录的命名风格格式化符号,详情见[文件风格](/read/go-zero-1.7-zh/d068.md)
type| []string| YES| `nil`| 结构体类型名称
#### 使用示例
以下我们以生成一个 User 结构体为例。
示例 1: 生成带缓存的代码
进入用户 Home 目录
$ cd ~
创建 demo 目录
$ mkdir demo && cd demo
生成 mongo 代码
$ goctl model mongo --type User --dir cache --cache
查看目录结构
$ tree . └── cache ├── error.go ├── usermodel.go ├── usermodelgen.go └── usertypes.go
1 directory, 4 files
查看代码
* error.go
* usermodel.go
* usermodelgen.go
* usertypes.go
package model
import ( "errors"
"github.com/zeromicro/go-zero/core/stores/mon"
)
var ( ErrNotFound = mon.ErrNotFound ErrInvalidObjectId = errors.New("invalid objectId") )
#####  tip
用户自定义代码在这个文件编写
package model
import ( "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/monc" )
var _ UserModel = (*customUserModel)(nil)
type ( // UserModel is an interface to be customized, add more methods here, // and implement the added methods in customUserModel. UserModel interface { userModel }
customUserModel struct {
*defaultUserModel
}
)
// NewUserModel returns a model for the mongo. func NewUserModel(url, db, collection string, c cache.CacheConf) UserModel { conn := monc.MustNewModel(url, db, collection, c) return &customUserModel{ defaultUserModel: newDefaultUserModel(conn), } }
#####  tip
此文件的头部带有 `DO NOT EDIT` 标识,因此不能修改此文件代码,代码重新生成会覆盖此文件。
// Code generated by goctl. DO NOT EDIT. package model
import ( "context" "time"
"github.com/zeromicro/go-zero/core/stores/monc"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
var prefixUserCacheKey = "cache:user:"
type userModel interface { Insert(ctx context.Context, data User) error FindOne(ctx context.Context, id string) (User, error) Update(ctx context.Context, data *User) error Delete(ctx context.Context, id string) error }
type defaultUserModel struct { conn *monc.Model }
func newDefaultUserModel(conn monc.Model) defaultUserModel { return &defaultUserModel{conn: conn} }
func (m defaultUserModel) Insert(ctx context.Context, data User) error { if data.ID.IsZero() { data.ID = primitive.NewObjectID() data.CreateAt = time.Now() data.UpdateAt = time.Now() }
key := prefixUserCacheKey + data.ID.Hex()
_, err := m.conn.InsertOne(ctx, key, data)
return err
}
func (m defaultUserModel) FindOne(ctx context.Context, id string) (User, error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return nil, ErrInvalidObjectId }
var data User
key := prefixUserCacheKey + id
err = m.conn.FindOne(ctx, key, &data, bson.M{"_id": oid})
switch err {
case nil:
return &data, nil
case monc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m defaultUserModel) Update(ctx context.Context, data User) error { data.UpdateAt = time.Now() key := prefixUserCacheKey + data.ID.Hex() _, err := m.conn.ReplaceOne(ctx, key, bson.M{"_id": data.ID}, data) return err }
func (m *defaultUserModel) Delete(ctx context.Context, id string) error {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return ErrInvalidObjectId
}
key := prefixUserCacheKey + id
_, err = m.conn.DeleteOne(ctx, key, bson.M{"_id": oid})
return err
}
package model
import ( "time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type User struct {
ID primitive.ObjectID bson:"_id,omitempty" json:"id,omitempty"
// TODO: Fill your own fields
UpdateAt time.Time bson:"updateAt,omitempty" json:"updateAt,omitempty"
CreateAt time.Time bson:"createAt,omitempty" json:"createAt,omitempty"
}
示例 2: 生成不带缓存的代码
进入用户 Home 目录
$ cd ~
创建 demo 目录
$ mkdir demo && cd demo
生成 mongo 代码
$ goctl model mongo --type User --dir nocache
查看目录结构
$ tree . └── nocache ├── error.go ├── usermodel.go ├── usermodelgen.go └── usertypes.go
1 directory, 4 files
查看代码
* error.go
* usermodel.go
* usermodelgen.go
* usertypes.go
package model
import ( "errors"
"github.com/zeromicro/go-zero/core/stores/mon"
)
var ( ErrNotFound = mon.ErrNotFound ErrInvalidObjectId = errors.New("invalid objectId") )
#####  tip
用户自定义代码在这个文件编写
package model
import "github.com/zeromicro/go-zero/core/stores/mon"
var _ UserModel = (*customUserModel)(nil)
type ( // UserModel is an interface to be customized, add more methods here, // and implement the added methods in customUserModel. UserModel interface { userModel }
customUserModel struct {
*defaultUserModel
}
)
// NewUserModel returns a model for the mongo. func NewUserModel(url, db, collection string) UserModel { conn := mon.MustNewModel(url, db, collection) return &customUserModel{ defaultUserModel: newDefaultUserModel(conn), } }
#####  tip
此文件的头部带有 `DO NOT EDIT` 标识,因此不能修改此文件代码,代码重新生成会覆盖此文件。
// Code generated by goctl. DO NOT EDIT. package model
import ( "context" "time"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type userModel interface { Insert(ctx context.Context, data User) error FindOne(ctx context.Context, id string) (User, error) Update(ctx context.Context, data *User) error Delete(ctx context.Context, id string) error }
type defaultUserModel struct { conn *mon.Model }
func newDefaultUserModel(conn mon.Model) defaultUserModel { return &defaultUserModel{conn: conn} }
func (m defaultUserModel) Insert(ctx context.Context, data User) error { if data.ID.IsZero() { data.ID = primitive.NewObjectID() data.CreateAt = time.Now() data.UpdateAt = time.Now() }
_, err := m.conn.InsertOne(ctx, data)
return err
}
func (m defaultUserModel) FindOne(ctx context.Context, id string) (User, error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return nil, ErrInvalidObjectId }
var data User
err = m.conn.FindOne(ctx, &data, bson.M{"_id": oid})
switch err {
case nil:
return &data, nil
case mon.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m defaultUserModel) Update(ctx context.Context, data User) error { data.UpdateAt = time.Now()
_, err := m.conn.ReplaceOne(ctx, bson.M{"_id": data.ID}, data)
return err
}
func (m *defaultUserModel) Delete(ctx context.Context, id string) error { oid, err := primitive.ObjectIDFromHex(id) if err != nil { return ErrInvalidObjectId }
_, err = m.conn.DeleteOne(ctx, bson.M{"_id": oid})
return err
}
package model
import ( "time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type User struct {
ID primitive.ObjectID bson:"_id,omitempty" json:"id,omitempty"
// TODO: Fill your own fields
UpdateAt time.Time bson:"updateAt,omitempty" json:"updateAt,omitempty"
CreateAt time.Time bson:"createAt,omitempty" json:"createAt,omitempty"
}
#### 新增自定义 model 方法示例
在以上代码生成中可以看出,每张表生成都会有 4 个文件,其中 `xxmodel.go` 和 `xxmodelgen.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`
最终代码如下,灰色底纹部分为新增自定义新增内容
package nocache
import ( "context" "fmt" "github.com/zeromicro/go-zero/core/stores/sqlx" )
var _ UserModel = (*customUserModel)(nil)
type ( // UserModel is an interface to be customized, add more methods here, // and implement the added methods in customUserModel. UserModel interface { userModel List(ctx context.Context, page, limit int) ([]*User, error) }
customUserModel struct {
*defaultUserModel
}
)
func (c customUserModel) List(ctx context.Context, page, limit int) ([]User, error) { query := fmt.Sprintf("select %s from %s limit ?,?", userRows, c.table) var resp []User err := c.conn.QueryRowsCtx(ctx, &resp, query, (page-1)limit, limit) return resp, err }
// NewUserModel returns a model for the database table. func NewUserModel(conn sqlx.SqlConn) UserModel { return &customUserModel{ defaultUserModel: newUserModel(conn), } }
#### 忽略字段控制
在 goctl 代码生成逻辑中,生成后的代码会在执行插入或者更新操作时会忽略某些字段的赋值,如 `create_time`,`Update_time` 等,目前 goctl 默认内置了 `create_at`, `create_time`, `created_at`, `update_at`, `update_time`, `updated_at`) 字段,在某些场景下 开发者可能不需要忽略,或者忽略的字段名称不为这些,开发者可以通过 `--ignore-columns (-i)` 进行控制,当 `--ignore-columns (-i)` 传值为空时 则跳过对 column 进行忽略,如果需要指定某些字段,则传具体值即可。
* 示例 1:跳过 column 忽略
必须显示传值为空字符串
$ goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -i ''
...
var (
studentFieldNames = builder.RawFieldNames(&Student{})
studentRows = strings.Join(studentFieldNames, ",")
studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames), ",")
studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "type"), "=?,") + "=?"
)
...
* 示例 2:指定某些 column 忽略
...
var (
studentFieldNames = builder.RawFieldNames(&Student{})
studentRows = strings.Join(studentFieldNames, ",")
studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames, "column1", "column2"), ",")
studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "type", "column1", "column2"), "=?,") + "=?"
)
...
--ignore-columns 支持通过英文逗号分割的字符串来传多个值,也支持指定多个参数来传多个只
$ goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -i 'column1,column2'
以上 shell 等同于
$ 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 文件,数据库连接两个来源生成代码。
$ goctl model mysql --help Generate mysql model
Usage: goctl model mysql [command]
Available Commands: datasource Generate model from datasource ddl Generate mysql model from ddl
Flags: -h, --help help for mysql -i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time]) --strict Generate model in strict mode
Use "goctl model mysql [command] --help" for more information about a command.
#### goctl model mysql datasource 指令
goctl model mysql datasource 指令用于从数据库连接生成 model 代码。
$ goctl model mysql datasource --help Generate model from datasource
Usage: goctl model mysql datasource [flags]
Flags: --branch string The branch of the remote repo, it does work with --remote -c, --cache Generate code with cache [optional] -d, --dir string The target dir -h, --help help for datasource --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 --idea For idea plugin [optional] --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 The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md] -t, --table strings The table or table globbing patterns in the database --url string The data source of database,like "root:password@tcp(127.0.0.1:3306)/database"
Global Flags:
-i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time])
--strict Generate model in strict mode
`` 参数字段| 参数类型| 是否必填| 默认值| 参数说明
---|---|---|---|---
branch| string| NO| 空字符串| 远程模板所在 git 分支名称,仅当remote有值时使用
cache| boolean| NO|false| 是否生成带缓存的代码
dir| string| NO| 当前工作目录| 代码输出目录
easy| boolean| NO|false| 是否暴露集合名称变量
home| string| NO|${HOME}/.goctl| 本地模板文件目录
remote| string| NO| 空字符串| 远程模板所在 git 仓库地址,当此字段传值时,优先级高于home字段值
style| string| NO|gozero| 输出文件和目录的命名风格格式化符号,详情见[文件风格](/read/go-zero-1.7-zh/d068.md)
table| []string| YES|nil| 需要生成代码的表
url| string| YES| 空字符串| 数据库连接,格式{{username}}:{{password}}@tcp({{host_port}})/{{db}}
ignore-columns| []string| NO|nil| 需要忽略的字段,插入或者更新时需要忽略的字段,如create_timestrict| boolean| NO|false| 是否是严格模式,如果是严格模式下,会对unsigned修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为bigint类型,如果为unsigned修饰则对应的 golang 数据类型就为int64,否则为uint64,如果 strict 为 false,则不关注unsigned` 修饰
goctl model mysql ddl 指令
goctl model mysql ddl 指令用于从 sql 文件生成 model 代码。
$ goctl model mysql ddl --help
Generate mysql model from ddl
Usage:
goctl model mysql ddl [flags]
Flags:
--branch string The branch of the remote repo, it does work with --remote
-c, --cache Generate code with cache [optional]
--database string The name of database [optional]
-d, --dir string The target dir
-h, --help help for ddl
--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
--idea For idea plugin [optional]
--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
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
-s, --src string The path or path globbing patterns of the ddl
--style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
Global Flags:
-i, --ignore-columns strings Ignore columns while creating or updating rows (default [create_at,created_at,create_time,update_at,updated_at,update_time])
--strict Generate model in strict mode
``` 参数字段| 参数类型| 是否必填| 默认值| 参数说明
---|---|---|---|---
branch| string| NO| 空字符串| 远程模板所在 git 分支名称,仅当 `remote` 有值时使用
cache| boolean| NO| `false`| 是否生成带缓存的代码
dir| string| NO| 当前工作目录| 代码输出目录
easy| boolean| NO| `false`| 是否暴露集合名称变量
home| string| NO| `${HOME}/.goctl`| 本地模板文件目录
remote| string| NO| 空字符串| 远程模板所在 git 仓库地址,当此字段传值时,优先级高于 `home` 字段值
src| string| YES| 空字符串| sql 文件路径
style| string| NO| `gozero`| 输出文件和目录的命名风格格式化符号,详情见[文件风格](/read/go-zero-1.7-zh/d068.md)
ignore-columns| []string| NO| `nil`| 需要忽略的字段,插入或者更新时需要忽略的字段,如 `create_time`
strict| boolean| NO| `false`| 是否是严格模式,如果是严格模式下,会对 `unsigned` 修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为 `bigint` 类型,如果为`unsigned` 修饰则对应的 golang 数据类型就为 `int64`,否则为 `uint64`,如果 strict 为 false,则不关注 `unsigned` 修饰
#### MySQL 类型映射关系(稳定版本)
* strict 为 true 时,且 unsigned 修饰
* strict 不为 true 时
MySQL 类型| 是否为 null 约束| Golang 类型
---|---|---
bit| NO| byte
tinyint| NO| uint64
tinyint| YES| sql.NullInt64
smallint| NO| uint64
smallint| YES| sql.NullInt64
mediumint| NO| uint64
mediumint| YES| sql.NullInt64
int| NO| uint64
int| YES| sql.NullInt64
middleint| NO| uint64
middleint| YES| sql.NullInt64
int1| NO| uint64
int1| YES| sql.NullInt64
int2| NO| uint64
int2| YES| sql.NullInt64
int3| NO| uint64
int3| YES| sql.NullInt64
int4| NO| uint64
int4| YES| sql.NullInt64
int8| NO| iunt64
int8| YES| sql.NullInt64
integer| NO| uint64
integer| YES| sql.NullInt64
bigint| NO| uint64
bigint| YES| sql.NullInt64
float| NO| float64
float| YES| sql.NullFloat64
float4| NO| float64
float4| YES| sql.NullFloat64
float8| NO| float64
float8| YES| sql.NullFloat64
date| NO| time.Time
datetime| NO| time.Time
timstamp| NO| time.Time
time| NO| string
year| NO| int64
char| NO| string
varchar| NO| string
nvarchar| NO| string
nchar| NO| string
character| NO| string
longvarchar| NO| string
linestring| NO| string
multilinestring| NO| string
binary| NO| string
varbinary| NO| string
tinytext| NO| string
text| NO| string
mediumtext| NO| string
longtext| NO| string
enum| NO| string
set| NO| string
json| NO| string
blob| NO| string
longblob| NO| string
mediumblob| NO| string
tinyblob| NO| string
bool| NO| bool
bllean| NO| bool
MySQL 类型| 是否为 null 约束| Golang 类型
---|---|---
bit| NO| byte
tinyint| NO| int64
tinyint| YES| sql.NullInt64
smallint| NO| int64
smallint| YES| sql.NullInt64
mediumint| NO| int64
mediumint| YES| sql.NullInt64
int| NO| int64
int| YES| sql.NullInt64
middleint| NO| int64
middleint| YES| sql.NullInt64
int1| NO| int64
int1| YES| sql.NullInt64
int2| NO| int64
int2| YES| sql.NullInt64
int3| NO| int64
int3| YES| sql.NullInt64
int4| NO| int64
int4| YES| sql.NullInt64
int8| NO| int64
int8| YES| sql.NullInt64
integer| NO| int64
integer| YES| sql.NullInt64
bigint| NO| int64
bigint| YES| sql.NullInt64
float| NO| float64
float| YES| sql.NullFloat64
float4| NO| float64
float4| YES| sql.NullFloat64
float8| NO| float64
float8| YES| sql.NullFloat64
date| NO| time.Time
datetime| NO| time.Time
timstamp| NO| time.Time
time| NO| string
year| NO| int64
char| NO| string
varchar| NO| string
nvarchar| NO| string
nchar| NO| string
character| NO| string
longvarchar| NO| string
linestring| NO| string
multilinestring| NO| string
binary| NO| string
varbinary| NO| string
tinytext| NO| string
text| NO| string
mediumtext| NO| string
longtext| NO| string
enum| NO| string
set| NO| string
json| NO| string
blob| NO| string
longblob| NO| string
mediumblob| NO| string
tinyblob| NO| string
bool| NO| bool
bllean| NO| bool
### goctl model pg 指令
goctl model pg 指令用于从 PostgreSQL 数据库中生成 Go 语言代码。
$ goctl model pg --help Generate postgresql model
Usage: goctl model pg [flags] goctl model pg [command]
Available Commands: datasource Generate model from datasource
Flags: -h, --help help for pg
Use "goctl model pg [command] --help" for more information about a command.
#### goctl model pg datasource 指令
$ goctl model pg datasource --help Generate model from datasource
Usage: goctl model pg datasource [flags]
Flags:
--branch string The branch of the remote repo, it does work with --remote
-c, --cache Generate code with cache [optional]
-d, --dir string The target dir
-h, --help help for datasource
--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
--idea For idea plugin [optional]
--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
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
-s, --schema string The table schema (default "public")
--strict Generate model in strict mode
--style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
-t, --table string The table or table globbing patterns in the database
--url string The data source of database,like "postgres://root:password@127.0.0.1:5432/database?sslmode=disable"
`` 参数字段| 参数类型| 是否必填| 默认值| 参数说明
---|---|---|---|---
branch| string| NO| 空字符串| 远程模板所在 git 分支名称,仅当remote有值时使用
cache| boolean| NO|false| 是否生成带缓存的代码
dir| string| NO| 当前工作目录| 代码输出目录
easy| boolean| NO|false| 是否暴露集合名称变量
home| string| NO|${HOME}/.goctl| 本地模板文件目录
idea| boolean| NO|false| 是否为 idea 使用,终端请忽略此字段
remote| string| NO| 空字符串| 远程模板所在 git 仓库地址,当此字段传值时,优先级高于home字段值
strict| boolean| NO|false| 是否是严格模式,如果是严格模式下,会对unsigned修饰的字段转换为对应的数据类型,主要针对数值型,例如:如果数据库中列为bigint类型,如果为unsigned修饰则对应的 golang 数据类型就为int64,否则为uint64,如果 strict 为 false,则不关注unsigned修饰
style| string| NO|gozero| 输出文件和目录的命名风格格式化符号,详情见[文件风格](/read/go-zero-1.7-zh/d068.md)
table| []string| YES|nil`| 需要生成代码的表
url| string| YES| 空字符串| 数据库连接,格式 postgres://{{username}}:{{password}}@{{host_port}}/{{db}}?sslmode=disable
PostgreSQL 类型映射关系
| PostgreSQL 类型 | Golang 类型 |
|---|---|
| bool | bool |
| _bool | pq.BoolArray |
| boolean | bool |
| tinyint | int64 |
| smallint | int64 |
| mediumint | int64 |
| int | int64 |
| int1 | int64 |
| int2 | int64 |
| _int2 | pq.Int64Array |
| int3 | int64 |
| int4 | int64 |
| _int4 | pq.Int64Array |
| int8 | int64 |
| _int8 | pq.Int64Array |
| integer | int64 |
| _integer | pq.Int64Array |
| bigint | int64 |
| float | float64 |
| float4 | float64 |
| _float4 | pq.Float64Array |
| float8 | float64 |
| _float8 | pq.Float64Array |
| double | float64 |
| decimal | float64 |
| dec | float64 |
| fixed | float64 |
| real | float64 |
| bit | byte |
| date | time.Time |
| datetime | time.Time |
| timestamp | time.Time |
| time | string |
| year | int64 |
| linestring | string |
| multilinestring | string |
| nvarchar | string |
| nchar | string |
| char | string |
| _char | pq.StringArray |
| character | string |
| varchar | string |
| _varchar | pq.StringArray |
| binary | string |
| bytea | string |
| longvarbinary | string |
| varbinary | string |
| tinytext | string |
| text | string |
| _text | pq.StringArray |
| mediumtext | string |
| longtext | string |
| enum | string |
| set | string |
| json | string |
| jsonb | string |
| blob | string |
| longblob | string |
| mediumblob | string |
| tinyblob | string |
| ltree | []byte |
类型映射自定义
类型映射自定义只有试验版本才能使用,关于如何开启试验版本,请参考 goctl env,关于配置使用请参考 goctl config
示例 1. 修改 decimal 为 decimal.Decimal 类型
- 在需要生成 model 的工程中初始化配置
$ goctl config init
goctl.yaml generated in ~/workspace/go-zero/tools/goctl/goctl.yaml
- 修改类型映射关系
灰色底纹部分为自定义映射类型。
model:
types_map:
bigint:
null_type: sql.NullInt64
type: int64
unsigned_type: uint64
dec:
null_type: sql.NullFloat64
type: float64
decimal:
null_type: decimal.NullDecimal
pkg: github.com/shopspring/decimal
type: decimal.Decimal
...
添加 goctl 内置不支持的类型映射
我们在表中有一个 pg 的数据类型为 inet
-- auto-generated definition
create table student
(
id integer not null
constraint student_pk
primary key,
name varchar default ''::character varying not null,
age integer default 0 not null,
description integer not null,
ip_address inet default '0.0.0.0'::inet not null
);
alter table student
owner to postgres;
目前 goctl 内置类型映射不支持的类型,因此 goctl 会报错如下:
$ goctl model pg datasource --url="postgres://postgres:postgrespw@127.0.0.1:55000/postgres?sslmode=disable" --table="user,student" --dir .
Error: unsupported database type: inet
要解决如上问题,在以往 goctl 版本是不支持的,只能给内置类型映射规则添加规则,然后再发版本,但是现在只需要在配置文件中添加一条类型映射规则皆可。
前提要 goctl 版本大于等于 1.6.5,且开始实验性功能
- 查看 goctl 版本是否满足条件
$ goctl env
GOCTL_OS=darwin
GOCTL_ARCH=arm64
GOCTL_HOME=/Users/sh00414ml/.goctl
GOCTL_DEBUG=False
GOCTL_CACHE=/Users/sh00414ml/.goctl/cache
GOCTL_EXPERIMENTAL=on # 实验性功能管开如果为 off 则需要开启,开启命令为 goctl env -w GOCTL_EXPERIMENTAL=on
GOCTL_VERSION=1.6.5 # goctl 版本
PROTOC_VERSION=3.19.4
PROTOC_GEN_GO_VERSION=v1.28.0
PROTO_GEN_GO_GRPC_VERSION=1.2.0
- 在目标工程项目中初始化 goctl 配置
$ goctl config
goctl.yaml generated in ~/demo/goctl-config/goctl.yaml # 这里以自己电脑输出准,这里仅供参考
- 修改 goctl.yaml
增加目标数据类型及映射关系,这里添加一个 inet 的映射,示例如下灰色底纹部分
model:
types_map:
bigint:
null_type: sql.NullInt64
type: int64
unsigned_type: uint64
...
inet:
null_type: sql.NullString
type: string
- 再次生成 model 代码
goctl model pg datasource --url="postgres://postgres:postgrespw@127.0.0.1:55000/postgres?sslmode=disable" --table="user,student" --dir .
Done.
