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.mzph.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 的配置信息