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

简介: 经过周末两天回血,今天早早来到公司,准备把上周遗留的 BUG 修了,然后再多写几个 BUG。还没等我把双肩包放好,就看见群里有同事反馈,有一个表的数据没了。

经过周末两天回血,今天早早来到公司,准备把上周遗留的 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 天,想恢复到哪天的几点就恢复到哪天几点,体验简直不要太好,我想删库跑路都不行了。


目录
相关文章
|
2月前
|
数据管理 数据挖掘 调度
Django后端架构开发:URLconf到ORM深度剖析
Django后端架构开发:URLconf到ORM深度剖析
47 1
|
2月前
|
数据库 Python
Django ORM
【8月更文挑战第23天】
32 4
|
2月前
|
API 数据库 开发者
【独家揭秘】Django ORM高手秘籍:如何玩转数据模型与数据库交互的艺术?
【8月更文挑战第31天】本文通过具体示例详细介绍了Django ORM的使用方法,包括数据模型设计与数据库操作的最佳实践。从创建应用和定义模型开始,逐步演示了查询、创建、更新和删除数据的全过程,并展示了关联查询与过滤的技巧,帮助开发者更高效地利用Django ORM构建和维护Web应用。通过这些基础概念和实践技巧,读者可以更好地掌握Django ORM,提升开发效率。
23 0
|
2月前
|
SQL Go 数据库
Django入门到放弃之ORM多表操作
Django入门到放弃之ORM多表操作
|
2月前
|
SQL 关系型数据库 MySQL
Django入门到放弃之ORM单表操作
Django入门到放弃之ORM单表操作
|
3月前
|
SQL 数据库 Python
Django框架数据库ORM查询操作(6)
【7月更文挑战第6天】```markdown Django ORM常用数据库操作:1) 查询所有数据2) 根据ID查询 3) 精确查询 4) 分页排序
57 1
|
3月前
|
数据库 Python
Django数据库类库MySQLdb使用详解
在Django中使用MySQLdb数据库类库,需要遵循以下步骤: 1. 安装MySQLdb:首先,需要在你的Python环境中安装MySQLdb类库。可以使用pip工具进行安装,命令如下:`pip install mysqlclient` 1. 配置Django数据库设置:在Django的settings.py文件中,需要配置DATABASES字典,用于指定使用MySQLdb以及数据库的相关信息。配置样例如下: ``` DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',
52 3
|
3月前
|
数据库 Python
Django数据库类库MySQLdb使用详解
以上就是在Django中使用MySQLdb数据库类库的详细步骤。
15 1
|
4月前
|
SQL 缓存 数据库
Django中ORM性能调优
【6月更文挑战第19天】 1. **索引优化**:使用`db_index=True`为模型字段创建索引,提升查询速度。 2. **批量操作**:批量创建和更新,减少数据库交互。 3. **查询优化**:利用`select_related`和`prefetch_related`减少查询次数。 4. **缓存**:使用内置缓存或Redis减少数据库访问。 5. **异步任务**:用Celery处理耗时操作,提高响应速度。 6. **数据库连接池**:管理连接,减少创建和销毁开销。 7. **SQL直接操作**:在必要时用原生SQL,避免ORM性能瓶颈。 8. **分页查询**:减少数据传输,改善用
74 10
|
4月前
|
JSON 缓存 数据库
Django ORM的QuerySet:解锁数据库交互的魔法钥匙
Django ORM的QuerySet:解锁数据库交互的魔法钥匙