gorp更新不起作用

huangapple go评论77阅读模式
英文:

gorp Update not updating

问题

我在使用gorp更新postgresql数据库中的一行时遇到了问题。我能够成功地使用db.Exec运行更新操作,所有列都会更新为正确的信息,但是使用gorp时,我只能更新非sql.Null*字段,而其他字段保持不变。

这段代码中,db.Exec的更新操作是有效的:

db, _ := getDB()
db.Exec("UPDATE network SET ssid=$1,lat=$2,lon=$3,sec=$4,channel=$5,found=$6,datefirst=$7,datelast=$8,bssid=$9 WHERE id=$10",
    npr.Ssid, npr.Lat.Float64, npr.Lon.Float64, npr.Sec.String, npr.Channel.Int64, npr.Found, npr.Datefirst.String, npr.Datelast.String, npr.Bssid.String, getNetworkId(ssid))

而这段代码中的dbmap.Update操作则无效:

func updateNetwork(n *WirelessNetwork) {
    _, dbmap := getDB()
    _, err := dbmap.Update(n)
    if err != nil {
        log.Fatal("updateNetwork - ", err)
    }
}

希望这能帮到你。

英文:

Im having issues updating a row in my postgresql database with gorp, im successfully able run the update using db.Exec, all columns get updated with the right information, while with gorp im only able to update the non sql.Null* fields while the rest remain unchanged.

var db *sql.DB
var dbmap *gorp.DbMap

func getDB() (*sql.DB, *gorp.DbMap) {
	if db == nil {
	    var err error
	    db, err = sql.Open("postgres", "postgres://xxxxxxxx")
		db.SetMaxOpenConns(5)
		db.SetMaxIdleConns(0)
		dbmap = &gorp.DbMap{Db: db, Dialect: gorp.PostgresDialect{}}
    	dbmap.AddTableWithName(WirelessNetwork{}, "network").SetKeys(true, "Id")
		if err != nil {
    		log.Panic(err)
    	}
    }

    return db, dbmap
}

type WirelessNetwork struct {
    Id        int             `db:"id"`
    Ssid      string          `db:"ssid"`
    Lat       sql.NullFloat64 `db:"lat"`
    Lon       sql.NullFloat64 `db:"lon"`
    Sec       sql.NullString  `db:"sec"`
    Bssid     sql.NullString  `db:"bssid"`
    Channel   sql.NullInt64   `db:"channel"`
    Found     bool            `db:"found"`
    Datefirst sql.NullString  `db:"datefirst"`
    Datelast  sql.NullString  `db:"datelast"`
}

npr := new(WirelessNetwork)
npr.Id = getNetworkId(ssid)
npr.Ssid = ssid
npr.Lat = dbProbes[index].Lat
npr.Lon = dbProbes[index].Lon
npr.Sec = dbProbes[index].Sec
npr.Bssid = dbProbes[index].Bssid
npr.Channel = dbProbes[index].Channel
npr.Found = dbProbes[index].Found
npr.Datefirst = dbProbes[index].Datefirst
npr.Datelast = dbProbes[index].Datelast
npr.Found = true

This works

db, _ := getDB()
db.Exec("UPDATE network SET ssid=$1,lat=$2,lon=$3,sec=$4,channel=$5,found=$6,datefirst=$7,datelast=$8,bssid=$9 WHERE id=$10",
	npr.Ssid, npr.Lat.Float64, npr.Lon.Float64, npr.Sec.String, npr.Channel.Int64, npr.Found, npr.Datefirst.String, npr.Datelast.String, npr.Bssid.String, getNetworkId(ssid))

This does not

func updateNetwork(n *WirelessNetwork) {
    _, dbmap := getDB()
    _, err := dbmap.Update(n)
   if err != nil {
	    log.Fatal("updateNetwork - ", err)
   }
}

答案1

得分: 6

sql.Null* 类型是带有 Valid 布尔字段的结构体,用于指示值是否为 NULL。布尔字段的初始值为 false,所以除非你明确验证数据,否则会将 NULL 值发送到数据库。你没有告诉我们 dbProbes 是什么以及它如何获取数据,但如果它是通过以下方式初始化的:

dbProbes[index].Lat = sql.NullFloat64{Float64: lat}

那么 Valid 仍然为 false,你需要手动验证数据:

dbProbes[index].Lat = sql.NullFloat64{Float64: lat, Valid: true}

或者使用 Scan 方法:

err = dbProbes[index].Lat.Scan(lat)
英文:

sql.Null* types are structs with Valid boolean field, which tells if the value is NULL. The initial value for boolean is false, so unless you explicitly validate your data, you'll be sending NULLs to the database. You didn't tell us, what is dbProbes and how does it get the data, but if it's initialised with something like

dbProbes[index].Lat = sql.NullFloat64{Float64: lat}

then Valid is still false, and you need to either validate your data manually:

dbProbes[index].Lat = sql.NullFloat64{Float64: lat, Valid: true}

or use the Scan method:

err = dbProbes[index].Lat.Scan(lat)

huangapple
  • 本文由 发表于 2015年6月8日 16:03:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/30703965.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定