обновление gorp не обновляется

У меня проблемы с обновлением строки в моей базе данных postgresql с помощью gorp, я успешно запускаю обновление с помощью db.Exec, все столбцы обновляются с правильной информацией, в то время как с помощью gorp я могу обновлять только поля, отличные от sql.Null*, в то время как остальные остаются без изменений.

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

Это работает

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))

Это не

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

person norwat    schedule 08.06.2015    source источник
comment
вы можете использовать sql-логирование gorp, чтобы увидеть запрос github.com/go-gorp/gorp #sql-логгирование   -  person fzerorubigd    schedule 13.06.2015


Ответы (1)


Типы sql.Null* — это структуры с логическим полем Valid, которое сообщает, является ли значение NULL. Начальное значение для логического значения равно false, поэтому, если вы явно не подтвердите свои данные, вы будете отправлять NULL в базу данных. Вы не сказали нам, что такое dbProbes и как он получает данные, но если он инициализируется чем-то вроде

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

тогда Valid по-прежнему ложно, и вам нужно либо проверить свои данные вручную:

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

или используйте метод Scan:

err = dbProbes[index].Lat.Scan(lat)
person Ainar-G    schedule 13.06.2015
comment
Спасибо за ответ, это сработало для меня, но стало немного некрасиво, есть ли более простой способ сделать это? Прежде чем я опубликовал этот вопрос, у меня было npr := dbProbes[index], где dbProbes — это часть WirelessNetwork, но это также не сработало. Теперь с вашим решением я должен установить каждое свойство этой структуры? - person norwat; 14.06.2015
comment
@norwat Это все еще зависит от того, откуда dbProbes. Я не могу ничего рекомендовать, не зная этого, но если бы вы могли проверить свои данные там, npr := dbProbes[index] снова заработало бы. - person Ainar-G; 14.06.2015
comment
Извините, забыл упомянуть, что dbProbes происходит из другой таблицы, в которой также хранятся WirelessNetwork объекты, затем я пытаюсь сопоставить элементы одной таблицы с другой на основе пользовательского ввода. Таким образом, по сути, dbProbes соответствует объекту sql со всеми допустимыми полями, а npr - новому объекту только с двумя допустимыми полями. - person norwat; 14.06.2015
comment
Все ли данные в другой таблице имеют значение NULL? Если это не так, я бы сказал, что проблема в том, как вы извлекаете данные из этой другой таблицы. Также я не совсем понимаю вашу последнюю фразу. Должны ли npr быть всеми NULL, кроме двух полей? - person Ainar-G; 14.06.2015
comment
нет, dbProbes происходит из таблицы, в которой все поля не равны нулю, и да, npr имеет только два ненулевых поля - person norwat; 15.06.2015
comment
Если значения находятся в таблице, и вы по-прежнему получаете из нее NULL, проверьте код, который их извлекает, и, возможно, откройте новый вопрос об этом. Как только это будет решено, вы можете просто обнулить ненужные поля npr. - person Ainar-G; 15.06.2015