2 回答

TA貢獻1827條經驗 獲得超9個贊
上一篇:我跑了go get -u github.com/jinzhu/gorm
。我將使用sqlite
而不是pgsql
. 供參考,go version go1.12.7 linux/amd64
您的注釋未使用正確的語法。gorm-屬性-值對的分隔符不是
comma
,而是semi-colon
。https://github.com/jinzhu/gorm/blob/master/model_struct.go#L644的實現
Date.Scan()
必須使用指針接收器,否則您會丟失更新的值。https://github.com/jinzhu/gorm/blob/0fd395ab37aefd2d50854f0556a4311dccc6f45a/scaner_test.go#L57在我的測試期間,
Scan
方法收到一個time.Time
,因此不需要nil
大小寫,也不string
需要大小寫(可能是數據庫驅動程序的問題)。然而,更重要的是,我添加了一個default
案例來捕獲不受支持的類型。該
Scan
方法涉及將從數據庫讀取的數據分配給您提供的對象的過程。評論它與您在上次 sql 結果復制粘貼中演示的缺失日期問題無關。我認為這在某種程度上與我之前提到的問題有關。我聽取了所有錯誤以確保一切按預期工作。
這是我的測試代碼,
package main
import (
"database/sql/driver"
"encoding/json"
"fmt"
"log"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
var DB *gorm.DB
type CustomerBroker struct {
gorm.Model
StartDate Date `gorm:"type:date;column:start_date" json:"start_date"`
EndDate Date `gorm:"type:date;column:end_date" json:"end_date"`
}
type Date struct {
time.Time
}
func (d *Date) UnmarshalJSON(b []byte) (err error) {
if b[0] == '"' && b[len(b)-1] == '"' {
b = b[1 : len(b)-1]
}
// take care of null..
if len(b) == 0 || string(b) == "null" {
d.Time = time.Time{}
return
}
d.Time, err = time.Parse("2006-01-02", string(b))
return
}
func (d *Date) Scan(b interface{}) (err error) {
switch x := b.(type) {
case time.Time:
d.Time = x
default:
err = fmt.Errorf("unsupported scan type %T", b)
}
return
}
func (d Date) Value() (driver.Value, error) {
// check if the date was not set..
if d.Time.IsZero() {
return nil, nil
}
return d.Time.Format("2006-01-02"), nil
}
func main() {
var dberr error
DB, dberr = gorm.Open("sqlite3", ":memory:")
if dberr != nil {
panic(dberr)
}
defer DB.Close()
record := CustomerBroker{}
errs := DB.CreateTable(record).GetErrors()
fmt.Println("create error ", errs)
data := []byte(`{"start_date": "2019-05-29", "end_date": null}`)
err := json.Unmarshal(data, &record)
fmt.Println("unmarshal error ", err)
log.Printf("record start %v end %v\n", record.StartDate, record.EndDate)
errs = DB.Create(&record).GetErrors()
fmt.Println("insert error ", errs)
all := []CustomerBroker{}
errs = DB.Find(&all).GetErrors()
fmt.Println("find error ", errs)
log.Printf("records count %v\n", len(all))
for _, a := range all {
log.Printf("found start %v end %v\n", a.StartDate, a.EndDate)
}
}
輸出:
$ go run main.go
create error []
unmarshal error <nil>
2019/10/11 17:22:51 record start 2019-05-29 00:00:00 +0000 UTC end 0001-01-01 00:00:00 +0000 UTC
insert error []
find error []
2019/10/11 17:22:51 records count 1
2019/10/11 17:22:51 found start 2019-05-29 00:00:00 +0000 UTC end 0001-01-01 00:00:00 +0000 UTC
如果您在運行此命令時發現不同的行為pqsql,請共享相應的 docker 映像,以便將來可以針對同一版本進行嘗試。

TA貢獻1831條經驗 獲得超4個贊
啟用DB.LogMode(true)
顯示這兩個查詢
與掃描:
[2019-10-16?14:03:34]??[0.97ms]??INSERT??INTO?"custom_brokers"?("created_at","updated_at","deleted_at","start_date","end_date")?VALUES?('2019-10-16?14:03:34','2019-10-16?14:03:34',NULL,'2019-05-29',NULL)?RETURNING?"custom_brokers"."id"
無需掃描:
[2019-10-16?14:02:53]??[0.76ms]??INSERT??INTO?"custom_brokers"?("created_at","updated_at","deleted_at")?VALUES?('2019-10-16?14:02:53','2019-10-16?14:02:53',NULL)?RETURNING?"custom_brokers"."id"
第二個顯示 gorm 完全忽略模型中的另一列(嵌入式 gorm 模型除外)
- 2 回答
- 0 關注
- 162 瀏覽
添加回答
舉報