postgresql使用gorm遇到的问题
2019 年 10 月 10 日
[TOC]
背景
最近接手了一个使用postgresql的项目,说真的,第一次在项目中使用。
我使用的是iris
+gorm
, 踩到了坑,花了一天才解决。
Array字段问题
解决办法是使用github.com/lib/pq
使用示例
package models
import "github.com/lib/pq"
type Info struct {
ID uint64
Title *string `gorm:"not null"`
Pic pq.StringArray `gorm:"type:varchar(100)[]"`
}
JSON 字段问题
解决办法是自定义一个JSON
类型, 在gorm的issue中找到的。
type JSON []byte
func (j JSON) Value() (driver.Value, error) {
if j.IsNull() {
return nil, nil
}
return string(j), nil
}
func (j *JSON) Scan(value interface{}) error {
if value == nil {
*j = nil
return nil
}
s, ok := value.([]byte)
if !ok {
errors.New("Invalid Scan Source")
}
*j = append((*j)[0:0], s...)
return nil
}
func (m JSON) MarshalJSON() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
return m, nil
}
func (m *JSON) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("null point exception")
}
*m = append((*m)[0:0], data...)
return nil
}
func (j JSON) IsNull() bool {
return len(j) == 0 || string(j) == "null"
}
func (j JSON) Equals(j1 JSON) bool {
return bytes.Equal([]byte(j), []byte(j1))
}
使用示例
package models
import "github.com/lib/pq"
type Info struct {
PubRes JSON `sql:"type:json" json:"object,omitempty"`
AuditRes string
}
time字段问题
golang对应的是time.Time, 但是time
是形如08:00:00
的形式,导致解析失败。
解决办法也是自定义类型。
type LocalTime time.Time
//转为数据库对象
func (l LocalTime) Value() (driver.Value, error) {
stamp := fmt.Sprintf("\"%s\"", time.Time(l).Format("15:04:05"))
return stamp, nil
}
//数据库对象转过来
func (l *LocalTime) Scan(value interface{}) error {
s, ok := value.(time.Time)
if !ok {
errors.New("Invalid Scan Source")
}
*l = LocalTime(s)
return nil
}
//对象变字符串
func (l LocalTime) MarshalJSON() ([]byte, error) {
stamp := fmt.Sprintf("\"%s\"", time.Time(l).Format("15:04:05"))
return []byte(stamp), nil
}
//字符串变对象
func (l *LocalTime) UnmarshalJSON(data []byte) error {
if l == nil {
return errors.New("null point exception")
}
//去掉前后的"
t, err := time.Parse("15:04:05", string(data[1:len(data)-1]))
if err != nil {
return err
}
*l = LocalTime(t)
return nil
}
使用示例
type Merchant struct {
Base
ID uint64 `gorm:"primary_key" json:"id"`
AutoPubTime *LocalTime `gorm:"type:time" json:"auto_pub_time,editable"`
}