在我目前的go项目(~5K LOC)中,我使用sqlite3作为我的底层数据库层,我使用gorm作为我的ORM引擎.其中一个模型是Platform具有PlatformType枚举类型的字段.这是一个代码片段来演示我的问题.
package main
import (
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/jinzhu/gorm"
"database/sql/driver"
"fmt"
)
/****************************\
Object Layer
\****************************/
// Platform ID
type PlatformID string
func (u *PlatformID) Scan(value interface{}) error { *u = PlatformID(value.([]byte)); return nil }
func (u PlatformID) Value() (driver.Value, error) { return string(u), nil }
// Platform Type enumeration
type PlatformType int
const (
PLATFORM_TYPE_NOT_A_VALUE PlatformType = iota
PLATFORM_TYPE_TYPE1
PLATFORM_TYPE_TYPE2
)
var types = [...]string {
"Not a type",
"Type1",
"Type2",
}
func (platform_type PlatformType) String() string {
return types[platform_type]
}
func (u *PlatformType) Scan(value interface{}) error { *u = PlatformType(value.(int)); return nil }
func (u PlatformType) Value() (driver.Value, error) { return int(u), nil }
// Platform descriptor.
type Platform struct {
ID PlatformID `json:"ID" gorm:"type:varchar(100);unique;not null"` // Assigned by LCBO.
Type PlatformType `json:"Type" gorm:"type:integer"`
}
type PlatformStore interface {
Init() error
Save(platform *Platform) error
}
/****************************\
Persist Layer
\****************************/
func NewSqlite3Store(dbname string) *gorm.DB {
db, err := gorm.Open("sqlite3", dbname)
if err != nil {
panic("failed to connect database")
}
return db
}
type DBPlatformStore struct {
db *gorm.DB
}
func NewDBPlatformStore(db *gorm.DB) PlatformStore {
return &DBPlatformStore{
db: db,
}
}
func (store *DBPlatformStore) Init() error {
err := store.db.AutoMigrate(&Platform{}).Error
if err != nil {
panic(err)
}
return err
}
func (store *DBPlatformStore) Save(platform *Platform) error {
err := store.db.Create(platform).Error
if err != nil {
panic(err)
}
return err
}
/****************************\
Application Layer
\****************************/
func main() {
db := NewSqlite3Store("enum_test.db")
platformStore := NewDBPlatformStore(db)
fmt.Println("Initialize Database")
err := platformStore.Init()
if err != nil {
panic(err)
}
platform := new(Platform)
platform.ID = "12345"
platform.Type = PLATFORM_TYPE_TYPE1
platformStore.Save(platform)
}
Run Code Online (Sandbox Code Playgroud)
运行上面的代码后,我得到了一个运行时错误"SQL:转换Exec的说法#1的类型:非数值类型为int的返回值"
]# go run enumtest.go
Initialize Database
panic: sql: converting Exec argument #1's type: non-Value type int returned from Value
goroutine 1 [running]:
panic(0x66d380, 0xc8203ae350)
/*/panic.go:481 +0x3e6
main.(*DBPlatformStore).Save(0xc820020b20, 0xc820304500, 0x0, 0x0)
/*/enumtest.go:84 +0x9f
main.main()
/*/enumtest.go:106 +0x247
exit status 2
Run Code Online (Sandbox Code Playgroud)
我检查了我的数据库,platforms表已成功创建.
]# sqlite3 enum_test.db
sqlite> .schema platforms
CREATE TABLE "platforms" ("id" varchar(100) NOT NULL UNIQUE,"type" integer , PRIMARY KEY ("id"));
Run Code Online (Sandbox Code Playgroud)
(不那么)微不足道的问题是如何修改我的代码,以便我可以正确地将条目保存到数据库.
我更大的问题是:如何将自定义的GO枚举类型保存到SQL数据库?(希望有ORM引擎)
根据当前的数据库/ SQL文档时,sql具有返回四个内建函数driver.Value,和底层类型是int64,float64,string和bool.所以我猜这是唯一支持的四种类型.
我刚刚从改变底层的类型我枚举int到int64,事情正在努力.
有问题的部分更新为以下代码段:
// Platform Type enumeration
type PlatformType int64
const (
PLATFORM_TYPE_NOT_A_VALUE PlatformType = iota
PLATFORM_TYPE_TYPE1
PLATFORM_TYPE_TYPE2
)
var types = [...]string {
"Not a type",
"Type1",
"Type2",
}
func (platform_type PlatformType) String() string {
return types[platform_type]
}
func (u *PlatformType) Scan(value interface{}) error { *u = PlatformType(value.(int64)); return nil }
func (u PlatformType) Value() (driver.Value, error) { return int64(u), nil }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3112 次 |
| 最近记录: |