我如何在 gorm 中添加枚举?

How can i add enum in gorm?

我正在编写 PostgreSQL table 模式。

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

那么我如何添加“SEDAN”、“HATCHBACK”、“MINIVAN”等车型作为 enum 数据类型

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

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

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

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 `sql:"car_type"`
}

func (MyTable) TableName() string {
    return "my_table"
}

旁注 - 如果您决定采用稍微不同的方法: 您可以将您的枚举定义为 int,并利用 iota。那么您可以使用代码生成器来创建 sql Scaner/Valuer 以及 json/text 表示。 例如: 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
    }
}