将枚举值保存到数据库

时间:2014-06-17 12:58:16

标签: sql types enums go

我是Go的新手,我正在尝试编写一个小程序来将枚举值保存到数据库中。 我声明我的值的方式如下:

type FileType int64
const (
    movie FileType = iota
    music
    book
    etc
)

我在我的结构中使用这些值,如下所示:

type File struct {
    Name     string
    Type     FileType
    Size     int64
}

我使用gorp作为我的数据库内容,但我猜gorp的使用与我的问题无关。我把东西放在我的数据库中这样:

dbmap.Insert(&File{"MyBook.pdf",movie,1000})

但是当我尝试检索东西时......

dbmap.Select(&dbFiles, "select * from Files")

我收到以下错误:

panic: reflect.Set: value of type int64 is not assignable to type main.FileType

当我使用int64作为const(...)File.Type字段的类型时,一切正常,但我是Go的新手,想要了解问题。 我看待它的方式,我有两个问题:

  1. 为什么不能成功转换这个东西?我查看了Go反射和sql包的源代码,并且有这种转换的方法,但它们似乎都失败了。这是一个错误吗?有什么问题?
  2. 我想通过实现以下方法可以实现sql.Scanner接口:

    Scan(src interface{}) error
    

    我尝试实现该方法,我甚至能够从src获取正确的值并将其转换为FileType,但如果我应该为“{{{ 1}}或(f *FileType)。无论哪种方式调用该方法,但是我无法覆盖(f FileType)(或者至少后来更新丢失)并且f实例从数据库的File值始终为“0”。

  3. 你对这两点有什么想法吗?

3 个答案:

答案 0 :(得分:26)

我最近有同样的需求,解决方案是实现两个接口:

  1. sql/driver.Valuer
  2. sql.Scanner
  3. 这是一个有效的例子:

    type FileType int64
    
    func (u *FileType) Scan(value interface{}) error { *u = FileType(value.(int64)); return nil }
    func (u FileType) Value() (driver.Value, error)  { return int64(u), nil }
    

答案 1 :(得分:8)

稍微偏离主题,但可能对其他人有用,因为在golang中使用postgres枚举字段(以字节形式返回)时解决类似问题时我一直在重新审视此问题/答案。

 // Status values
 const ( 
     incomplete Status = "incomplete"
     complete   Status = "complete" 
     reject     Status = "reject"
 )

 type Status string

 func (s *Status) Scan(value interface{}) error {
     asBytes, ok := value.([]byte)
     if !ok {
         return errors.New("Scan source is not []byte")
     }
     *s = Status(string(asBytes))
     return nil
 }

 func (s SubjectStatus) Value() (driver.Value, error) {
     // validation would go here
     return string(s), nil
 }

答案 2 :(得分:0)

  1. Go需要特定于类型,有时可能会很痛苦。
  2. (f FileType)(f *FileType)便宜,而#34;本地"类型,除非你有一个复杂的类型,否则几乎总是更好地不使用指针。
  3. 你的意思是什么它没有覆盖它?修改后你重新保存了结构吗?