go gorm 更新的时候不会更新空字段

发布时间 2024-01-04 10:29:40作者: 若-飞

做个记录,gorm在更新字段的时候,如果字符串字段是空的,那么将不会更新到数据库。

在使用gorm将一个字段更新为空的时候,发现并不生效,不了解具体什么原因,所以此时需要打开debug模式,查看原生SQL是如何执行的。
 
type Student struct {
Model
    Email       string  `form:"email" json:"email"`
Name string`form:"name"  json:"name"`
}

func(c *Content) update(content Content) (err) {
    err = db.Model(&Content{}).Debug().Where("id = ?", 123).Update(&content).Error
}
查看日志便知,此时如果name为空字符串,那么update的sql语句中并不会set,后查阅,方知gorm对于空字符和0这种数据,认为是不需要处理的,所以。。。

这边暂时采用map[string]interface{}来进行更新

var curBadgeClaim *BadgeClaim
		getRes := uc.data.DB(ctx).Model(&badgeClaim).
			Where(BadgeClaim{ClaimData: &apiBadgeV1.ClaimData{UserId: badgeClaim.UserId, BadgeId: badgeClaim.BadgeId}}).
			Find(&curBadgeClaim)
		if getRes.Error != nil {
			err = getRes.Error
			return
		}
		if curBadgeClaim == nil || getRes.RowsAffected == 0 {
			err = uc.data.DB(ctx).Create(&badgeClaim).Error
			if err != nil {
				return
			}
			curBadgeClaim = badgeClaim
		} else {
			// 由于json:"err,omitempty" 空字符串不写入,所以这边单独设置map
			updMap := map[string]interface{}{
				"claim_status":     badgeClaim.ClaimStatus,
				"claim_time":       badgeClaim.ClaimTime,
				"transaction_hash": badgeClaim.TransactionHash,
				"user_attrs":       badgeClaim.UserAttrs,
				"err":              badgeClaim.Err,
			}
			db := uc.data.DB(ctx).Model(&badgeClaim).
				Where(BadgeClaim{ClaimData: &apiBadgeV1.ClaimData{UserId: badgeClaim.UserId, BadgeId: badgeClaim.BadgeId}}).
				Updates(updMap)
			if db.Error != nil {
				uc.log.WithContext(ctx).Warnf(fmt.Sprintf("ClaimUsecase::Replace badgeClaim:%v  err:%v", badgeClaim, db.Error))
				err = db.Error
				return
			}
		}