如何在表单中添加enum ?



我正在写PostgreSQL表模式

type TestTable struct {
ID        int    `gorm:"column:id;primaryKey;autoIncrement"`
CarType   string `gorm:"column:car_type"`
}

那么我如何添加像"轿车"、"掀背"、"minivan"这样的汽车类型呢?enum 数据类型

假设您正在使用GORM与PostgreSQL。首先在数据库中创建一个类型。

CREATE TYPE car_type AS ENUM (
'SEDAN',
'HATCHBACK',
'MINIVAN');

那么您将需要定义以下模型:

import "database/sql/driver"
type carType string
const (
SEDAN  carType = "SEDAN"
HATCHBACK carType = "HATCHBACK"
MINIVAN carType = "MINIVAN"
)
func (ct *carType) Scan(value interface{}) error {
*ct = carType(value.([]byte))
return nil
}
func (ct carType) Value() (driver.Value, error) {
return string(ct), nil
}
type MyTable struct {
gorm.Model
CarType carType `gorm:"type:car_type"`
}
func (MyTable) TableName() string {
return "my_table"
}

注意MySQL用户,你可以添加结构标记gorm:sql:,这样你就不必运行原始查询在数据库中创建enum。

CarType carType `gorm:"type:enum('SEDAN', 'HATCHBACK', 'MINIVAN')";"column:car_type"`

CarType carType `sql:"type:ENUM('SEDAN', 'HATCHBACK', 'MINIVAN')" gorm:"column:car_type"`

编辑:有人指出这只适用于MySQL。我想把我的答案拿下来,但是使用MySQL的人可能会发现它很有帮助。

这里有一个不需要事先创建SQL类型的答案。这个解决方案的来源是这个github问题

对于您的字段标签,使用如下:

type TestTable struct {
ID        int     `gorm:"column:id;primaryKey;autoIncrement"`
CarType   carType `sql:"type:ENUM('SEDAN', 'HATCHBACK', 'MINIVAN')" gorm:"column:car_type"`
}

您还需要添加附加到carType类型的Scan和Value方法。

type carType string
const (
SEDAN carType = "SEDAN"
HATCHBACK carType = "HATCHBACK"
MINIVAN carType = "MINIVAN"
)
func (self *carType) Scan(value interface{}) error {
*self = carType(value.([]byte))
return nil
}
func (self carType) Value() (driver.Value, error) {
return string(self), nil
}

附带说明-如果您决定采用稍微不同的方法:您可以将枚举定义为int,并利用iota。然后你可以使用代码生成器创建sqlScaner/Valuer,也json/文本表示。例如:https://github.com/dmarkham/enumer

为了扩展Nick的回答,我为自动化添加了以下内容:

假设你有DBClient结构体,你可以创建一个方法来创建这个汽车类型:

func (psqlClient *DBClient) CreateCarTypeEnum() error {
result := psqlClient.db.Exec("SELECT 1 FROM pg_type WHERE typname = 'car_type';")
switch {
case result.RowsAffected == 0:
if err := psqlClient.db.Exec("CREATE TYPE car_type AS ENUM ('SEDAN', 'HATCHBACK', 'MINIVAN');").Error; err != nil {
log.Error().Err(err).Msg("Error creating car_type ENUM")
return err
}
return nil
case result.Error != nil:
return result.Error
default:
return nil
}
}

就像你在sql中写的那样,你可以使用type和添加任何你想要的数据类型。

type MyTable struct {
CarType    string `gorm:"column:car_type;type:enum('SEDAN','HATCHBACK','MINIVAN')" json:"car_type"`
}

一个更新,它将不与sql:"car_type"工作,而是使用gorm:"car_type"。当您在数据库中手动创建了自定义enum类型后,也是如此。

https://gorm.io/docs/data_types.html =>impl Scan &值方法。


如果enum是由协议生成的,可以使用这个插件

https://github.com/yangyang5214/protoc-gen-gorm-serializer。

# task.proto
syntax = "proto3";
enum TaskStatus {
Unknown = 0;
Running = 1;
Exiting = 2;
Pending = 3;
}

# gen gorm-serializer.pb.go
protoc --proto_path=.  --go_out=paths=source_relative:. --gorm-serializer_out=paths=source_relative:.  task.proto
# use 
type Task struct {
gorm.Model
Name   string
Status example.TaskStatus `gorm:"type:int"`
}

相关内容

  • 没有找到相关文章

最新更新