I can't find it now
https://github.com/jinzhu/gorm/issues/628 it was supported in the past, right?
Comment From: qshuai
Yeah. Refer to the following example:
type Ecosystem string
const (
Production Ecosystem = "production"
TestSystem Ecosystem = "testsystem"
)
func (e *Ecosystem) Scan(value interface{}) error {
*e = Ecosystem(value.([]byte))
return nil
}
func (e Ecosystem) Value() (driver.Value, error) {
return string(e), nil
}
// model define
Ecosystem Ecosystem `json:"ecosystem" sql:"type:ENUM('production', 'testsystem')"`
Comment From: paqio
getting
pq: type "enum" does not exist
Any solutions?
Comment From: Entrio
same here, a whole quest to find an answer
Comment From: AlexThurston
Anyone find an answer to this?
Comment From: 4nte
+1?
Comment From: friend0
I'm not able to use enums in postgres either. @qshuai the above example is non-op
Comment From: qshuai
The sample works for me, but in mysql. postgres have not been tested.
Comment From: friend0
Hmm, it would be good to get another pg user to verify, but looks like this may be missing functionality? I could maybe take a look at a PR if someone else can verify it's not user error
Comment From: MithunArunan
Getting the same error, pq: type "enum" does not exist
Comment From: atoami
Is there any updates for this issue? We need to resolve this issue ASAP.
Comment From: sillygod
For postgresql, you should define the type in the struct tag as the following
ex.
type XXX struct {
Platform DevicePlatform `sql:"type:platform"`
}
platform is a data type as enum in my case. You should use the data type instead of type:ENUM(... in the struct tag.
Comment From: atoami
@sillygod Can you upload full example please? For instance, with enum of platform("ios", "android"). Thanks.
Comment From: sillygod
@sillygod Can you upload full example please? For instance, with enum of platform("ios", "android"). Thanks.
Hi @atoami, I have to say if you want to use the gorm's auto migration with the enum in PostgreSQL, it will not work. However, you can perform CRUD with enum in PostgreSQL.
First, let's prepare the database, I create the enum manually.
CREATE TYPE phone_model AS ENUM (
'unknown',
'sony',
'pixel');
Then define the example model.
type phoneModel string
const (
sony phoneModel = "sony"
pixel phoneModel = "pixel"
)
func (p *phoneModel) Scan(value interface{}) error {
*p = phoneModel(value.([]byte))
return nil
}
func (p phoneModel) Value() (driver.Value, error) {
return string(p), nil
}
type Phone struct {
gorm.Model
Name string
PhoneModel phoneModel `sql:"type:phone_model"`
}
func (Phone) TableName() string {
return "phone"
}
The key point is to use sql:"type:phone_model" instead. You will get pq: type "enum" does not exist if you try to use sql:"enum('unknown', 'sony', 'pixel')".
Because the enum is defined at first, you can use gorm's AutoMigration to create table here.
db.AutoMigrate(&Phone{})
Finally, you can test about inserting a new row.
if err := db.Create(&Phone{
Name: "alice",
PhoneModel: sony,
}).Error; err != nil {
panic(err)
}
Comment From: github-actions[bot]
This issue will be automatically closed because it is marked as GORM V1 issue, we have released the public testing GORM V2 release and its documents https://v2.gorm.io/docs/ already, the testing release has been used in some production services for a while, and going to release the final version in following weeks, we are still actively collecting feedback before it, please open a new issue for any suggestion or problem, thank you
Also check out https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft for how to use the public testing version and its changelog
Comment From: ykchong45
I found on a Chinese site that the following syntax works for MySQL enum type definition:
gorm:"type:enum('published', 'pending', 'deleted');default:'pending'"
Comment From: bluebrown
I found on a Chinese site that the following syntax works for MySQL enum type definition:
gorm:"type:enum('published', 'pending', 'deleted');default:'pending'"
This didnt work for me. I stumm got type enum does not exist.
Comment From: nielvid
I found on a Chinese site that the following syntax works for MySQL enum type definition:
gorm:"type:enum('published', 'pending', 'deleted');default:'pending'"
This works for me in mysql
Comment From: Linchin
Why does this type definition start with lower case? Is it because we don't want this type to be public?
type phoneModel string
Comment From: ilhm-rai
for postgresql declare this syntax before auto migration
db.Debug().Exec(`
DO $$ BEGIN
CREATE TYPE enum_name AS ENUM ('value1', 'value2');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;`)
db.Debug().AutoMigrate(...)
Comment From: abishz17
sql:"type:enum('Published', 'Pending', 'Deleted');default:'Pending'"
This tag works perfectly with gorm's automigrate in postgres.
Comment From: nkbhasker
I have recently done something like this with Atlas.
Define enum
type GenderEnum string
const (
MALE GenderEnum = "MALE"
FEMALE GenderEnum = "FEMALE"
)
func (e *GenderEnum) Scan(value interface{}) error {
str, ok := value.(string)
if !ok {
return fmt.Errorf("invalid str")
}
*e = GenderEnum(str)
return nil
}
func (e GenderEnum) Value() (interface{}, error) {
return string(e), nil
}
Define model with enum field
type User struct {
gorm.Model
Name string
Email string
Gender *enums.GenderEnum `gorm:"type:gender"`
}
Create a migration script with enums and models
func main() {
sb := &strings.Builder{}
loadEnums(sb)
loadModels(sb)
io.WriteString(os.Stdout, sb.String())
}
func loadEnums(sb *strings.Builder) {
enums := []string{
`CREATE TYPE gender AS ENUM (
'MALE',
'FEMALE'
);`,
}
for _, enum := range enums {
sb.WriteString(enum)
sb.WriteString(";\n")
}
}
func loadModels(sb *strings.Builder) {
models := []interface{}{
&models.User{},
}
stmts, err := gormschema.New("postgres").Load(models...)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load gorm schema: %v\n", err)
os.Exit(1)
}
sb.WriteString(stmts)
sb.WriteString(";\n")
}
Create an atlas.hcl file
data "external_schema" "gorm" {
program = ["go", "run", "./migrate.go"]
}
env "gorm" {
src = data.external_schema.gorm.url
dev = "docker://postgres/16/dev"
migration {
dir = "file://migrations"
}
format {
migrate {
diff = "{{ sql . \" \" }}"
}
}
}
Link to example repository go-gorm-atlas-example