go用xorm去update数据库的一个坑

    最近写API服务比较多,一般试验性质的用python flask简单又快,需要稍微考虑点儿并发性能的,那还是用go来写咯。API服务一般都要落盘写库,随便选了个xorm来写mysql数据库。
    但是最近碰到一个有点儿奇怪的现象,调用端报告偶有数据没有更新的现象。回头去查代码,写库这段逻辑如下:
 if _, err = session.Where("col1 = ?", d.col1).Update(d); err != nil {
    glog.Infof("has result col1:%s updated!", d.col1)
    return
}


    一眼就能看明白的一个调用,看不出有啥毛病啊-_-b
    试图重现也没能重现,于是只能加debug log以图能保存下次发生时的事发现场。结果过了一个月果然又出现了。确实是这段代码更新表中数据时出错了。
    后来搜xorm文档时发现了这么一个Q&A:
https://www.kancloud.cn/kancloud/xorm-manual-zh-cn/56018
  • 我的struct里面包含bool类型,为什么它不能作为条件也没法用Update更新?
答:默认bool类型因为无法判断是否为空,所以不会自动作为条件也不会作为Update的内容。可以使用UseBool函数,也可以使用Cols函数
engine.Cols("bool_field").Update(&Struct{BoolField:true})
// UPDATE struct SET bool_field = true
 
    深受启发啊!我出问题的数据虽然不是bool,但是0!于是又去查了下文档,发现xorm的帮助文档在一个角落里果然提到了bool false, int 0, 空nil都默认不会更新!好坑啊!这种update默认方式的设计简直是反人类啊!
    解决方法如上所述,要么比如对bool用UseBool函数强制更新,要么用Cols函数指定哪些列要强制更新。但我比较懒,干脆全部列都强制更新完事儿,改动如下:
 if _, err = session.Where("col1 = ?", d.col1).AllCols().Update(d); err != nil {
    glog.Infof("has result col1:%s updated!", d.col1)
    return
}

 
 

评论

  1. 亲 用allcols更新空字符串那种列还是无效的 你自己可以试试 只能用cols 包括用omit去说明不更新哪些也是无效的

    回复删除
    回复
    1. 所以我觉得索性直接用exec方法去写update的sql语句就好了 xorm的update真的很鸡肋啊 反而比我写语句都麻烦了

      删除

发表评论

此博客中的热门博文

Windows上调试C/C++程序时自动产生coredump的设置方法

利用Gitlab的Jira issue tracker实现Jira issue自动根据Gitlab commit/merge更新状态