我有一个MySQL表,它的模式中有一个带有not null default current_timestamp on update current_timestamp属性的updated_at时间戳列。我已经使用UPDATE查询在MySQL工作台中手动测试了该模式,并且我了解到,只有当没有为updated_at列提供特定值时,on update current_timestamp属性才会生效;但是,当提供了特定值时,将保存所提供的值。这是所需的行为。
接下来,我将使用gorm在我的go项目中处理DAO内容。对于更新表中的行,一切都运行得非常好,直到我需要实现一个只更新last_login时间戳列而不更新updated_at列的方法。
由于某些原因(可能是因为我在模式中设置了on update current_timestamp ),无论如何,gorm生成的实际SQL都会在UPDATE查询中设置updated_at。因此,我认为为了防止更新,也许我应该提供一个预先从SELECT查询检索到的时间戳值(一起放在一个事务中)。但不幸的是,尽管我为gorm的update()方法提供了一个特定值,但gorm忽略了它,并以任何方式更新列以使用最新的时间戳。
DAO update方法中的go代码如下所示:
err := db.Model(&user).
Omit("user_id").
Updates(user).
Error用户结构看起来像这样:
type User struct {
UserID uint64 `gorm:"primaryKey"`
LastLogin *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}LastLogin字段接受一个指针来允许在MySQL中设置null值;不管怎样,这个字段没有问题。
更新代码大致如下所示:
// retrieve current user row
found, err := s.DAO.FindUserByID(ctx, accountID, userID)
if err != nil {
return err
}
// create a struct with existing UpdatedAt value
user := &User{
UserID: userID,
LastLogin: lastLogin,
UpdatedAt: found.UpdatedAt, // trying to prevent defaulting to current timestamp
}
// call the DAO update method
err = s.DAO.UpdateUser(ctx, *user)
return err尽管已经显式设置了UpdatedAt的值,gorm还是忽略了它,并将当前时间戳放入生成的SQL查询中。
我该如何解决这个问题呢?
发布于 2021-03-01 18:35:00
有一种方法。
Gorm的Update/Updates方法将忽略您为UpdatedAt传递的任何值,并使用当前时间戳。这是设计好的。
您可以使用Omit("UpdatedAt")让gorm不更新UpdatedAt字段。但是,当您这样做时,由于on update current_timestamp的原因,数据库仍将设置updated_at列。
解决这个问题的方法是使用UpdateColumns方法,它显式地不执行时间跟踪:
err := db.Model(&user).
Omit("user_id").
UpdateColumns(User{
LastLogin: lastLogin,
UpdatedAt: found.UpdatedAt,
}).
Error
// error check总而言之,我会考虑放弃on update子句,因为它干扰/复制了Gorm正在做的事情。
https://stackoverflow.com/questions/66415974
复制相似问题