python中使用單例模式在整個程序中只創建一個數據庫連接,節省資源

示例代碼:

from loguru import logger
from pymongo import MongoClient
from pymongo.errors import ConnectionFailurefrom llm_engineering.settings import settingsclass MongoDatabaseConnector:_instance: MongoClient | None = Nonedef __new__(cls, *args, **kwargs) -> MongoClient:if cls._instance is None:try:cls._instance = MongoClient(settings.DATABASE_HOST)except ConnectionFailure as e:logger.error(f"Couldn't connect to the database: {e!s}")raiselogger.info(f"Connection to MongoDB with URI successful: {settings.DATABASE_HOST}")return cls._instanceconnection = MongoDatabaseConnector()

詳細解釋

  1. 導入依賴模塊

    from loguru import logger
    
    • 作用:導入 loguru 庫中的 logger 對象。這個對象用于記錄日志信息,比標準庫中的 logging 更加方便和直觀。
    • 舉例:當程序運行時,可以用 logger.info("提示信息") 打印一條信息,比如記錄連接成功或失敗的日志。
    from pymongo import MongoClient
    
    • 作用:導入 pymongo 庫中的 MongoClient 類。這個類用來創建與 MongoDB 數據庫的連接。
    • 舉例:假如你需要連接一個 MongoDB 數據庫,其地址為 "mongodb://127.0.0.1:27017",就可以用 MongoClient("mongodb://127.0.0.1:27017") 來創建連接對象。
    from pymongo.errors import ConnectionFailure
    
    • 作用:從 pymongo 庫中導入 ConnectionFailure 異常類,當連接數據庫失敗時,這個異常會被拋出。
    • 舉例:如果數據庫地址錯誤或者數據庫沒有啟動,會拋出 ConnectionFailure 異常,我們可以捕獲這個異常并記錄錯誤日志。
    from llm_engineering.settings import settings
    
    • 作用:導入項目中 llm_engineering.settings 模塊中的 settings 對象。這個對象通常存儲配置參數,比如數據庫的 URI 地址。
    • 舉例:假設在 settings 中有定義 DATABASE_HOST = "mongodb://127.0.0.1:27017",那么代碼會使用這個地址來連接數據庫。
  2. 定義 MongoDatabaseConnector 類

    class MongoDatabaseConnector:_instance: MongoClient | None = None
    
    • 作用:定義一個類 MongoDatabaseConnector,用來管理 MongoDB 的連接。這里使用了一個類變量 _instance 來存儲連接實例。
    • 解釋_instance 初始值為 None,表示當前還沒有創建數據庫連接。類型提示 MongoClient | None 表示這個變量可能是一個 MongoClient 對象,也可能是 None
  3. 重寫 new 方法實現單例模式

    def __new__(cls, *args, **kwargs) -> MongoClient:if cls._instance is None:try:cls._instance = MongoClient(settings.DATABASE_HOST)except ConnectionFailure as e:logger.error(f"Couldn't connect to the database: {e!s}")raiselogger.info(f"Connection to MongoDB with URI successful: {settings.DATABASE_HOST}")return cls._instance
    
    • 作用__new__ 是 Python 中的一個特殊方法,用于在創建實例之前進行控制。這里重寫它實現了“單例模式”,即無論你創建多少次這個類的實例,都只會返回同一個 MongoClient 連接對象。

    • 詳細步驟

      • 判斷是否已存在連接

        if cls._instance is None:
        
        • 意思:如果 _instance 還是 None(表示還沒有連接實例),則繼續創建新的連接。
      • 嘗試建立數據庫連接

        try:cls._instance = MongoClient(settings.DATABASE_HOST)
        
        • 作用:調用 MongoClient 構造函數,使用 settings.DATABASE_HOST(例如 "mongodb://127.0.0.1:27017")來創建數據庫連接。
        • 舉例:假設 settings.DATABASE_HOST 定義為 "mongodb://192.168.1.100:27017",那么代碼會試圖連接到 IP 為 192.168.1.100、端口為 27017 的 MongoDB 實例。
      • 異常處理

        except ConnectionFailure as e:logger.error(f"Couldn't connect to the database: {e!s}")raise
        
        • 作用:如果連接失敗(例如數據庫沒有啟動、地址錯誤等),會捕獲 ConnectionFailure 異常。
        • 解釋:程序會通過 logger.error 輸出錯誤日志,然后使用 raise 將異常繼續拋出,確保調用者知道連接出了問題。
        • 舉例:若連接失敗并拋出異常,比如錯誤代碼為 10061(連接被拒絕),錯誤日志會顯示 "Couldn't connect to the database: [錯誤信息]"
      • 記錄成功日志

        logger.info(f"Connection to MongoDB with URI successful: {settings.DATABASE_HOST}")
        
        • 作用:不論是首次連接還是復用已有連接,都記錄一條信息日志,表明連接成功。
        • 舉例:如果成功連接到 "mongodb://192.168.1.100:27017",日志中會顯示 "Connection to MongoDB with URI successful: mongodb://192.168.1.100:27017"
      • 返回連接實例

        return cls._instance
        
        • 作用:返回創建好的 MongoClient 實例。這樣,無論何時調用 MongoDatabaseConnector(),最終返回的都是同一個連接實例。
  4. 創建連接實例

    connection = MongoDatabaseConnector()
    
    • 作用:調用 MongoDatabaseConnector() 來獲取 MongoDB 的連接實例。
    • 解釋:這行代碼實際上會觸發上面定義的 __new__ 方法,判斷是否需要創建新連接或直接返回已有連接。最終,變量 connection 存儲了一個 MongoClient 對象。
    • 舉例:如果第一次調用時創建連接,則 connection 可能代表一個連接到 "mongodb://192.168.1.100:27017" 的 MongoClient 實例;后續再調用時將復用這個實例。

總結

  • 單例模式:該代碼使用了單例模式保證整個程序中只會創建一個數據庫連接。這樣可以避免重復創建連接資源,提升效率。
  • 錯誤處理:使用 try...except 捕獲連接失敗的情況,并通過日志記錄錯誤信息,然后拋出異常,確保問題不會被忽略。
  • 日志記錄:通過 logurulogger 對象,詳細記錄了連接的成功與失敗狀態,方便排查問題。
  • 實際場景舉例
    假設你的數據庫地址為 "mongodb://192.168.1.100:27017",第一次執行 MongoDatabaseConnector() 時:
    • 程序檢查 _instanceNone
    • 連接成功后,將 MongoClient("mongodb://192.168.1.100:27017") 賦值給 _instance
    • 輸出日志 “Connection to MongoDB with URI successful: mongodb://192.168.1.100:27017”;
    • 將該連接實例返回并賦值給 connection
      如果之后再調用 MongoDatabaseConnector(),程序就直接返回已存在的連接實例,不再重新連接。

這樣寫的好處是節省資源簡化連接管理,同時通過日志記錄幫助開發者快速定位數據庫連接的問題。

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

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

相關文章

AI小白的第六天:必要的數學知識(一)

在學習的過程中,不管是上代碼還是理論學習,其中都摻雜了一些數學知識。俗話說“磨刀不誤砍柴工”,而我已經“誤了砍柴功”了,現在變成了“亡羊補牢,為時不晚”。 線性代數 線性代數是數學的一個分支,主要…

【Linux】Bash是什么?怎么使用?

李升偉 整理 什么是 Bash? Bash(Bourne Again Shell)是一種 命令行解釋器(Shell),廣泛用于 Unix 和 Linux 操作系統。它是 Bourne Shell(sh) 的增強版,提供了更多的功能…

Qt Creator入門

1.創建項目 選擇創建項目-Application(Qt)-Qt Widgets Application-修改名稱即可 默認創建有窗口類,myWidget,基類有三種選擇:QWidget,QMainWindow,QDialog 注意: 名稱和創建路徑不能有中文、…

C語言經典代碼練習題

1.輸入一個4位數&#xff1a;輸出這個輸的個位 十位 百位 千位 #include <stdio.h> int main(int argc, char const *argv[]) {int a;printf("輸入一個&#xff14;位數&#xff1a;");scanf("%d",&a);printf("個位&#xff1a;%d\n"…

cls(**dict(data, id=id))靈活地從一個字典生成實例,同時確保某些關鍵字段(如 id)被正確設置或覆蓋

示例代碼&#xff1a; classmethoddef from_mongo(cls: Type[T], data: dict) -> T:"""Convert "_id" (str object) into "id" (UUID object)."""if not data:raise ValueError("Data is empty.")id data.pop…

MyBatis XMLMapperBuilder 是如何將 SQL 語句解析成可執行的對象? 如何將結果映射規則解析成對應的處理器?

1. XMLMapperBuilder 如何將 SQL 語句解析成可執行對象 (MappedStatement): XMLMapperBuilder 解析 <select>, <insert>, <update>, <delete> 等 SQL 語句元素時&#xff0c;并不僅僅是簡單地讀取 SQL 文本&#xff0c;而是要將 SQL 語句和相關的配置…

咖啡點單小程序畢業設計(JAVA+SpringBoot+微信小程序+完整源碼+論文)

?全網粉絲20W,csdn特邀作者、博客專家、CSDN新星計劃導師、java領域優質創作者,博客之星、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取項目下載方式&#x1f345; 一、項目背景介紹&#xff1a; 隨著社會的快速發展和…

003-掌控命令行-CLI11-C++開源庫108杰

首選的現代C風格命令行參數解析器! &#xff08;本課程包含兩段教學視頻。&#xff09; 以文件對象監控程序為實例&#xff0c;五分鐘實現從命令行讀入多個監控目標路徑&#xff1b;區分兩大時機&#xff0c;學習 CLI11 構建與解析參數兩大場景下的異常處理&#xff1b;區分三…

【leetcode hot 100 124】二叉樹中的最大路徑和

解法一&#xff1a;&#xff08;遞歸&#xff09;考慮實現一個簡化的函數 maxGain(node)&#xff0c;該函數計算二叉樹中的一個節點的最大貢獻值&#xff0c;具體而言&#xff0c;就是在以該節點為根節點的子樹中尋找以該節點為起點的一條路徑&#xff0c;使得該路徑上的節點值…

譜分析方法

前言 本文隸屬于專欄《機器學習數學通關指南》&#xff0c;該專欄為筆者原創&#xff0c;引用請注明來源&#xff0c;不足和錯誤之處請在評論區幫忙指出&#xff0c;謝謝&#xff01; 本專欄目錄結構和參考文獻請見《機器學習數學通關指南》 ima 知識庫 知識庫廣場搜索&#…

在圖像/視頻中裁剪出人臉區域

1. 在圖像中裁剪人臉區域 import face_alignment import skimage.io import numpy from argparse import ArgumentParser from skimage import img_as_ubyte from skimage.transform import resize from tqdm import tqdm import os import numpy as np import warnings warni…

【軟考-架構】11.3、設計模式-新

?資料&文章更新? GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目錄 項目中的應用設計模式創建型設計模式結構型設計模式行為型設計模式 &#x1f4af;考試真題題外話 項目中的應用 在實際項目中&#xff0c;我應用過多種設計模式來解決不同…

使用Redis如何實現分布式鎖?(超賣)

分布式鎖概念 在多線程環境下&#xff0c;為了保證數據的線程安全&#xff0c;鎖保證同一時刻&#xff0c;只有一個可以訪問和更新共享數據。在單機系統我們可以使用 synchronized 鎖、Lock 鎖保證線程安全。 synchronized 鎖是 Java 提供的一種內置鎖&#xff0c;在單個 JVM …

Linux的Shell編程

一、什么是Shell 1、為什么要學習Shell Linux運維工程師在進行服務器集群管理時&#xff0c;需要編寫Shell程序來進行服務器管理。 對于JavaEE和Python程序員來說&#xff0c;工作的需要。Boss會要求你編寫一些Shell腳本進行程序或者是服務器的維護&#xff0c;比如編寫一個…

使用React和google gemini api 打造一個google gemini應用

實現一個簡單的聊天應用&#xff0c;用戶可以通過輸入問題或點擊“Surprise me”按鈕獲取隨機問題&#xff0c;并從后端API獲取回答。 import { useState } from "react"; function App() {const [ value, setValue] useState(""); // 存儲用戶輸入的問題…

深入探討TK矩陣系統:創新的TikTok運營工具

TK矩陣的應用場景 TK矩陣系統適用于多個場景&#xff0c;尤其是在以下幾個方面有顯著優勢&#xff1a; 批量賬號管理與內容發布&#xff1a;對于需要管理多個TikTok賬號的內容創作者或營銷人員&#xff0c;TK矩陣提供了高效的賬號管理工具&#xff0c;支持批量發布視頻、評論、…

MTK Android12 應用在最頂端時,禁止拉起其他某個應用(一)

1、需求 近期&#xff0c;客戶要求應用在最頂端時&#xff0c;禁止拉起其他某個應用2、解決方法 diff --git a/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java b/frameworks/base/services/core/java/com/android/server/wm/ActivityStarte…

論文閱讀筆記:Deep Unsupervised Learning using Nonequilibrium Thermodynamics

1、來源 論文連接1&#xff1a;http://ganguli-gang.stanford.edu/pdf/DeepUnsupDiffusion.pdf 論文連接2(帶appendix)&#xff1a;https://arxiv.org/pdf/1503.03585v7 代碼鏈接&#xff1a;https://github.com/Sohl-Dickstein/Diffusion-Probabilistic-Models 代碼的環境配置…

7種數據結構

7種數據結構 順序表sqlite.hseqlite.c 單鏈表linklist.clinklist.h 雙鏈表doulinklist.cdoulinklist.h 鏈式棧linkstack.clinkstack.h 隊列SeqQueue.cSeqQueue.h 樹tree.c 哈希表hash.c 順序表 sqlite.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ typedef struct person…

Linux 查看及測試網絡命令

使用 ifconfig 命令查看網絡接口地址 查看指定的網絡接口信息 執行 ifconfig ens33 命令可以只查看網卡 ens33 的配置信息