我正在写PostgreSQL表模式。
type TestTable struct { ID int `gorm:"column:id;primaryKey;autoIncrement"` CarType string `gorm:"column:car_type"` }
那么,我如何添加汽车类型,如“SEDAN”,“HATCHBACK”,“MINIVAN”作为enum数据类型
jv4diomz1#
假设你使用的是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:,这样您就不必运行原始查询来在数据库中创建枚举。
gorm:
sql:
CarType carType `gorm:"type:enum('SEDAN', 'HATCHBACK', 'MINIVAN')";"column:car_type"`
或
CarType carType `sql:"type:ENUM('SEDAN', 'HATCHBACK', 'MINIVAN')" gorm:"column:car_type"`
nszi6y052#
编辑:有人指出这只适用于MySQL。我会把我的答案写下来,但使用MySQL的人可能会发现它很有帮助。这里有一个不需要您事先创建SQL类型的答案。这个解决方案的来源是这个github issue对于字段标记,请使用以下命令:
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 }
b4qexyjb3#
顺便说一句-如果你决定用稍微不同的方法:你可以将你的枚举定义为int,并利用iota。然后你可以使用代码生成器来创建sql Scaner/Valuer,也可以创建json/text表示。例如:https://github.com/dmarkham/enumer
iota
Scaner/Valuer
68bkxrlz4#
为了扩展Nick的答案,我为自动化添加以下内容:假设你有DBClient结构体,你可以创建一个方法来创建这个汽车类型:
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 } }
5m1hhzi45#
就像你写在SQL中,你可以使用类型,并添加任何数据类型,你想像你写在SQL中。
type MyTable struct { CarType string `gorm:"column:car_type;type:enum('SEDAN','HATCHBACK','MINIVAN')" json:"car_type"` }
u2nhd7ah6#
一个更新,它将不与sql:"car_type"工作,而是使用gorm:"car_type"。在数据库中手动创建自定义枚举类型后,也是如此。
sql:"car_type"
gorm:"car_type"
mutmk8jj7#
https://gorm.io/docs/data_types.html => impl Scan & Value方法。如果enum是由protoc生成的,可以使用这个插件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"` }
7条答案
按热度按时间jv4diomz1#
假设你使用的是GORM和PostgreSQL。首先在数据库中创建一个类型。
然后,您需要定义以下模型:
对于MySQL用户,您可以添加结构标记
gorm:
或sql:
,这样您就不必运行原始查询来在数据库中创建枚举。或
nszi6y052#
编辑:有人指出这只适用于MySQL。我会把我的答案写下来,但使用MySQL的人可能会发现它很有帮助。
这里有一个不需要您事先创建SQL类型的答案。这个解决方案的来源是这个github issue
对于字段标记,请使用以下命令:
您还需要添加附加到carType类型的Scan和Value方法。
b4qexyjb3#
顺便说一句-如果你决定用稍微不同的方法:你可以将你的枚举定义为int,并利用
iota
。然后你可以使用代码生成器来创建sqlScaner/Valuer
,也可以创建json/text表示。例如:https://github.com/dmarkham/enumer68bkxrlz4#
为了扩展Nick的答案,我为自动化添加以下内容:
假设你有
DBClient
结构体,你可以创建一个方法来创建这个汽车类型:5m1hhzi45#
就像你写在SQL中,你可以使用类型,并添加任何数据类型,你想像你写在SQL中。
u2nhd7ah6#
一个更新,它将不与
sql:"car_type"
工作,而是使用gorm:"car_type"
。在数据库中手动创建自定义枚举类型后,也是如此。mutmk8jj7#
https://gorm.io/docs/data_types.html => impl Scan & Value方法。
如果enum是由protoc生成的,可以使用这个插件
https://github.com/yangyang5214/protoc-gen-gorm-serializer。