django與數據庫交互關于當前時間的坑

背景

在線上服務中使用時間進行數據庫操作時發現異常,而在本地環境無法成功復現此問題,導致難以進行故障排查。

核心問題

view.py

class XxxViewSet(viewsets.ModelViewSet):queryset = Xxx.objects.with_status().order_by("status", "-start_time")

managers.py

def with_status(self):"""添加status排序字段"""cur_time = datetime.now(pytz.utc)queryset = self.annotate(status=Case(When(end_time__lt=cur_time, then=Value(2)),When(start_time__gt=cur_time, then=Value(1)),default=Value(0),output_field=IntegerField(),))return queryset

問題的關鍵點

由于viewsets.ModelViewSet中使用了queryset屬性,程序不會在每次請求時都重新計算當前時間,而是使用緩存的查詢集。這意味著時間過濾條件并不會隨著時間實時更新,而是固定在視圖集類被加載時的時間。

分析本地無法復現原因

本地開發經常使用熱部署,即服務頻繁重啟,這導致定義的cur_time變量不斷被重置。而線上環境服務不會如此頻繁重啟,因而很難注意到這個問題。建議在本地創建一條時間精確到秒的記錄,以此來模擬線上環境并復現問題。

問題的根源

Django中與數據庫交互時,應使用Django數據庫函數中的當前時間而非Python標準庫中的時間:

使用Django的Now函數:

from django.db.models.functions import Now

而不是使用python 的時間

from datetime import datetime

否則會把時間設置為定值

從sql的角度理解就是
在這里插入圖片描述

最終方案

修改使用數據庫時間
managers.py

from django.db.models.functions import Now
def with_status(self):"""添加status排序字段"""cur_time = Now()queryset = self.annotate(status=Case(When(end_time__lt=cur_time, then=Value(2)),When(start_time__gt=cur_time, then=Value(1)),default=Value(0),output_field=IntegerField(),))return queryset

結論與建議

使用Django django.db.models.functions.Now()函數替代Python datetime.datetime.now()在Django應用程序的時間處理中具有幾個優點與潛在的缺點:

優點:

1.在Django數據庫交互時,如果需要獲取當前時間,應優先考慮使用django.db.models.functions.Now(),而不是datetime.datetime.now(),特別是當涉及到使用類屬性queryset的情況。這樣可以確保每次請求都能反映真實的當前時間,避免由于查詢集緩存所導致的時間判斷錯誤。確保時間數據的一致性與準確性。
2. 數據庫兼容性Now()函數自動適應不同數據庫系統的時間函數,降低了數據庫之間兼容性問題的風險。
3. 性能:如果數據庫后端支持,使用Now()可能會比從應用層傳遞時間戳到數據庫更優化,因為時間運算直接在數據庫層完成。
4. 時區一致性Now()函數遵守Django的時區設置,自動處理時區轉換,減少了手動處理時區問題的復雜度。

缺點:

  1. 依賴數據庫時鐘:使用Now()函數意味著依賴數據庫服務器的時鐘。如果數據庫服務器的時間配置不正確,可能會導致問題。
  2. 數據庫執行時間:由于Now()函數在數據庫執行查詢時生成時間,如果一個請求涉及多個查詢,而查詢之間有延遲,這可能會導致時間上的微小不一致。
  3. 測試復雜性:使用Now()可能會使單元測試更復雜,因為在測試環境中控制或模擬數據庫返回的Now()值通常比使用固定的datetime值更困難。

總結

  1. Django數據庫交互時,如果需要獲取當前時間,應優先考慮使用django.db.models.functions.Now(),而不是datetime.datetime.now(),特別是當涉及到使用類屬性queryset的情況。這樣可以確保每次請求都能反映真實的當前時間,避免由于查詢集緩存所導致的時間判斷錯誤。確保時間數據的一致性與準確性。
  2. 若使用queryset應該避免存在動態計算的情況,比如上述例子的status字段計算,queryset = Announcement.objects.all()程序不會在每次請求時都重新計算當前時間,而是使用緩存的查詢集。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208741.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208741.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208741.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【數據結構】插入排序,希爾排序,選擇排序,堆排序,冒泡排序

1.插入排序 思路:插入排序將一個數插入一個有序的數組里面,將這個數和數組元素挨著比較,直到他插入到合適的位置。 動畫演示: 步驟:1.定義一個變量tmp保存要插入的數據 2.在循環中用tmp和有序數組中的元素比較&#…

談一談Linux下的進程和線程

文章目錄 進程線程進程與線程比較 進程 什么是進程? 概念上來說,進程是擔當OS資源分配的實體。通俗來說,進程是我們OS上一個在運行的程序。 我們的OS上不止有一個進程,當我們的某一個進程像是去磁盤上讀文件時,由于磁…

學習pytorch18 pytorch完整的模型訓練流程

pytorch完整的模型訓練流程 1. 流程1. 整理訓練數據 使用CIFAR10數據集2. 搭建網絡結構3. 構建損失函數4. 使用優化器5. 訓練模型6. 測試數據 計算模型預測正確率7. 保存模型 2. 代碼1. model.py2. train.py 3. 結果tensorboard結果以下圖片 顏色較淺的線是真實計算的值&#x…

國產化軟件突圍!懌星科技eStation產品榮獲2023鈴軒獎“前瞻優秀獎”

11月11日,2023中國汽車供應鏈峰會暨第八屆鈴軒獎頒獎典禮在江蘇省昆山市舉行。懌星科技憑借eStation產品,榮獲2023鈴軒獎“前瞻智能座艙類優秀獎”,懌星CEO潘凱受邀出席鈴軒獎晚會并代表領獎。 2023鈴軒獎“前瞻智能座艙類優秀獎” 鈴軒獎&a…

el-table 跨頁多選

步驟一 在<el-table>中:row-key"getRowKeys"和selection-change"handleSelectionChange" 在<el-table-column>中type"selection"那列&#xff0c;添加:reserve-selection"true" <el-table:data"tableData"r…

隊列排序:給定序列a,每次操作將a[1]移動到 從右往左第一個嚴格小于a[1]的元素的下一個位置,求能否使序列有序,若可以,求最少操作次數

題目 思路&#xff1a; 賽時代碼&#xff08;先求右起最長有序區間長度&#xff0c;再求左邊最小值是否小于等于右邊有序區間左端點的數&#xff09; #include<bits/stdc.h> using namespace std; #define int long long const int maxn 1e6 5; int a[maxn]; int n; …

阿里云磁盤在線擴容

我們從阿里云的控制面板中給硬盤擴容后結果發現我們的磁盤空間并沒有改變 注意&#xff1a;本次操作是針對CentOS 7的 &#xfeff;#使用df -h并沒有發現我們的磁盤空間增加 #使用fdisk -l發現確實還有部分空間 運行df -h命令查看云盤分區大小。 以下示例返回分區&#xf…

python3安裝redis

#!/usr/bin/python3import os import platform import argparse import shutil# 自定義變量 default_system "ubuntu" default_redis_version "6.2.6" default_install_path "/usr/local/redis" default_local_package_dir os.path.dirname(…

eve-ng鏡像模擬設備-信息安全管理與評估-2023國賽

eve-ng鏡像模擬設備-信息安全管理與評估-2023國賽 author&#xff1a;leadlife data&#xff1a;2023/12/4 mains&#xff1a;EVE-ng 模擬器 - 信息安全管理與評估模擬環境部署 references&#xff1a; EVE-ng 官網&#xff1a;https://www.eve-ng.net/EVE-ng 中文網&#xff1…

嵌入版python作為便攜計算器(安裝及配置ipython)

今天用別的電腦調試C&#xff0c;需要計算反三角函數時發現沒有趁手工具&#xff0c;忽然想用python作為便攜計算器放在U盤&#xff0c;遂想到嵌入版python 懶得自己配可以直接下載&#xff0c;使用方法見第4節 1&#xff0c;下載embeddable python&#xff08;嵌入版python&…

React中傳入props.children后, 為什么會導致組件的重新渲染?

傳入props.children后, 為什么會導致組件的重新渲染&#xff1f; 問題描述 在 react 中, 我想要對組件的渲染進行優化, 遇到了一個非常意思的問題, 當我向一個組件中傳入了 props.children 之后, 每次父組件重新渲染都會導致這個組件的重新渲染; 它看起來的表現就像是被memo包…

【1day】?萬戶協同辦公平臺 convertFile 任意文件讀取漏洞學習

注:該文章來自作者日常學習筆記,請勿利用文章內的相關技術從事非法測試,如因此產生的一切不良后果與作者無關。 目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現

圖的鄰接鏈表儲存

噴了一節課 。。。。。。。、。 #include<stdio.h> #include<stdlib.h> #define MAXNUM 20 //每一個頂點的節點結構&#xff08;單鏈表&#xff09; typedef struct ANode{ int adjvex;//頂點指向的位置 struct ArcNode *next;//指向下一個頂點 …

C++ 內存分區模型

目錄 程序運行前 代碼區 全局區 程序運行后 new 在堆區開辟數據 delete釋放堆區數據 堆區開辟數組 內存分區模型 棧&#xff08;Stack&#xff09; 堆&#xff08;Heap&#xff09; 全局/靜態存儲區&#xff08;Global/Static Storage&#xff09; 常量存儲區&am…

力扣230. 二叉搜索樹中第K小的元素

深度優先搜索 思路&#xff1a; 二叉搜索樹的特性&#xff0c;通過中序遍歷得到有序序列&#xff0c;則遍歷到第K個節點的時候即為結果&#xff1b;使用棧通過深度優先遍歷進行中序遍歷&#xff1a; 先將節點和左子節點壓棧&#xff1b;然后棧頂上就是“最左”葉子節點&#x…

Linux DAC權限的簡單應用

Linux的DAC&#xff08;Discretionary Access Control&#xff09;權限模型是一種常見的訪問控制機制&#xff0c;它用于管理文件和目錄的訪問權限。作為一名經驗豐富的Linux系統安全工程師&#xff0c;我會盡可能以簡單明了的方式向計算機小白介紹Linux DAC權限模型。 在Linu…

jenkins中“Jenkins Plot Plugin”的使用方法,比較兩個excel的數據差異

Jenkins Plot Plugin是Jenkins的一個插件&#xff0c;它可以用于生成圖表和報表&#xff0c;以便更好地理解和分析構建和測試數據。下面是使用Jenkins Plot Plugin比較兩個Excel數據差異的步驟&#xff1a; 1.安裝Jenkins Plot Plugin&#xff1a;在Jenkins的插件管理頁面搜索…

使用 Axios 進行網絡請求的全面指南

使用 Axios 進行網絡請求的全面指南 本文將向您介紹如何使用 Axios 進行網絡請求。通過分步指南和示例代碼&#xff0c;您將學習如何使用 Axios 庫在前端應用程序中發送 GET、POST、PUT 和 DELETE 請求&#xff0c;并處理響應數據和錯誤。 準備工作 在開始之前&#xff0c;請…

電子學會C/C++編程等級考試2021年09月(五級)真題解析

C/C++等級考試(1~8級)全部真題?點這里 第1題:抓牛 農夫知道一頭牛的位置,想要抓住它。農夫和牛都位于數軸上,農夫起始位于點N(0<=N<=100000),牛位于點K(0<=K<=100000)。農夫有兩種移動方式: 1、從X移動到X-1或X+1,每次移動花費一分鐘 2、從X移動到2*X,每…

ubuntu18.04安裝opencv-4.5.5+opencv_contrib-4.5.5

一、安裝opencv依賴 sudo apt-get install build-essential sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-d…