社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

因为 Django ORM update,我今天差点「从删库到跑路」

yongxinz • 3 年前 • 374 次点击  
阅读 4

因为 Django ORM update,我今天差点「从删库到跑路」

经过周末两天回血,今天早早来到公司,准备把上周遗留的 BUG 修了,然后再多写几个 BUG。

还没等我把双肩包放好,就看见群里有同事反馈,有一个表的数据没了。

我一看,可不是,原来有几千条,现在就剩十几条了。

大脑迅速转了几圈,相关代码我还真改过,但已经是上上周的事了,初步判定,应该是跟我没关系。但是,身为一名乐于助人的红领巾,我还是要帮忙排查一下的。

事情大概是这样:

我们有一个定时程序,从数据源拉取数据,然后入到一个表里,没有则创建,有则更新。

还有一个定时程序,根据表的 update_time 字段来删除过期数据,过期时间是 7 天。

快速浏览了一下代码,感觉没有什么问题,同事也都表示,最近没动过相关代码。

初步判断,可能是数据源出问题了。

然后手动执行了一下拉取程序,数据源没有问题。

那就奇怪了,难道真是我上上周改的代码出问题了?

心虚使我的后背微微冒汗,怀着忐忑的心情把之前的代码仔细看了一遍。看完后,我眼前浮现出三个字:没问题。

又叫来两个同事一起来帮我 review 一下,三个人对着电脑屏幕,望眼欲穿,频频发出感叹:这没问题啊!

其中一个同事看我用的 update() 方法,说:“是不是数据没变化,update() 就不更新了呢?”

我和另一个同事同声反驳:“不会啊,怎么可能。”

我还补充道:“别这样,要对我们学的知识有自信。”

不过,也实在看不出到底哪里有问题,死马当活马医吧。

我又跑了一遍程序,没想到打脸来的如此之快,update_time 字段还真的没更新。

于是,我改了一点程序,确保入库数据和数据库中的数据是不同的,又跑了一遍。

发现我改的字段更新了,但是唯独 update_time 字段没更新。

然后我把 update() 方法改成 update_or_create() 方法又跑了一遍,因为我上次把 update_or_create() 改成了 update(), update_time 字段更新了。

纳尼?这到底是为啥啊?懵了~

赶紧找谷歌大哥帮帮忙。

一般我们定义 model 中的时间字段是这样的:

create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
复制代码

create_time 在第一次新增数据时创建,之后便不再改变,update_time 会在每次数据更新时更新。

但,update_time 并非每次都更新,比如使用上文提到的 update_or_create() 方法会更新,save() 方法也会更新。因为这两个方法都是走的 Django ORM。

而更适用于批量操作的 update() 方法则是直接执行数据库 SQL,不走 Django ORM,所以 update_time 也就得不到更新。那要想更新怎么办呢?手动给 update_time 赋值。

这也太坑了,程序欢天喜地执行了一周都没有问题,没想到隐藏了这么大的一个 BUG,真是学到了。

最后,感谢公司 DBA 大佬帮忙恢复数据,不论原因,过去 7 天,想恢复到哪天的几点就恢复到哪天几点,体验简直不要太好,我想删库跑路都不行了。

技术博客:

github.com/yongxinz/te…

同时,也欢迎关注我的微信公众号 AlwaysBeta,更多精彩内容等你来。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/72009
 
374 次点击