通過週末兩天回血,今天早早來到公司,準備把上週遺留的 BUG 修了,而後再多寫幾個 BUG。python
還沒等我把雙肩包放好,就看見羣裏有同事反饋,有一個表的數據沒了。git
我一看,可不是,原來有幾千條,如今就剩十幾條了。github
大腦迅速轉了幾圈,相關代碼我還真改過,但已是上上週的事了,初步斷定,應該是跟我不要緊。可是,身爲一名樂於助人的紅領巾,我仍是要幫忙排查一下的。數據庫
事情大概是這樣:微信
咱們有一個定時程序,從數據源拉取數據,而後入到一個表裏,沒有則建立,有則更新。spa
還有一個定時程序,根據表的 update_time 字段來刪除過時數據,過時時間是 7 天。code
快速瀏覽了一下代碼,感受沒有什麼問題,同事也都表示,最近沒動過相關代碼。cdn
初步判斷,多是數據源出問題了。blog
而後手動執行了一下拉取程序,數據源沒有問題。get
那就奇怪了,難道真是我上上週改的代碼出問題了?
心虛使個人後背微微冒汗,懷着忐忑的心情把以前的代碼仔細看了一遍。看完後,我眼前浮現出三個字:沒問題。
又叫來兩個同事一塊兒來幫我 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 天,想恢復到哪天的幾點就恢復到哪天幾點,體驗簡直不要太好,我想刪庫跑路都不行了。
技術博客:
同時,也歡迎關注個人微信公衆號 AlwaysBeta,更多精彩內容等你來。