python中使用单例模式在整个程序中只创建一个数据库连接,节省资源

news2025/3/19 15:31:15

示例代码:

from loguru import logger
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure

from llm_engineering.settings import settings


class MongoDatabaseConnector:
    _instance: MongoClient | None = None

    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}")
                raise

        logger.info(f"Connection to MongoDB with URI successful: {settings.DATABASE_HOST}")

        return cls._instance


connection = 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}")
                raise
    
        logger.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.coloradmin.cn/o/2317870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AIAgent有哪些不错的开源平台

AIAgent领域有许多优秀的开源平台和框架,以下是一些值得推荐的开源平台: AutoGPT AutoGPT 是一个基于 OpenAI 的 GPT-4 和 GPT-3.5 大型语言模型的开源框架,能够根据用户给定的目标自动生成所需提示,并利用多种工具 API 执行多步骤…

Python刷题:流程控制(上)

今天刷的是PythonTip的Python 入门挑战中的题,整体难度不高,适合小白练手以及巩固知识点。下面会进行详细讲解。 每日一句 每一个拼命努力的人,都像是独自穿越黑暗森林的行者, 没有并肩的身影,唯有孤独如影随形&…

vulhub/Billu_b0x靶机----练习攻略

1.Billu_b0x靶场下载链接: https://download.vulnhub.com/billu/Billu_b0x.zip 2.下载后,解压出ova文件,直接拖至VMware中,重命名和选择存储位置,点击导入,报错点击重试即可。修改网卡为NAT模式。 打开靶…

【YOLOv8】YOLOv8改进系列(8)----替换主干网络之Swin Transformer

主页:HABUO🍁主页:HABUO 🍁YOLOv8入门改进专栏🍁 🍁如果再也不能见到你,祝你早安,午安,晚安🍁 【YOLOv8改进系列】: 【YOLOv8】YOLOv8结构解读…

Qwen2-Audio:通义千问音频大模型技术解读

引言:从llm到mlm(audio) 大型语言模型(LLM)的发展日新月异,它们在文本理解、生成、推理等方面展现出惊人的能力。然而,交互模态不仅仅依赖于文字,语音、语调、环境音等听觉信息同样承载着丰富的内容。阿里巴巴通义千问团队,推出了 Qwen-Audio 系列模型,这里我们一起…

解决Java多张图合成JPG时出现红色前景及多列自适应适配

目录 前言 一、追本溯源 1、回到最开始 2、合成JPG的异常 二、解决问题 1、关于ImageType 2、TYPE_INT_RGB和TYPE_INT_ARGB 3、问题修复 4、列数自适应的问题 三、总结 前言 在当今数字化信息飞速发展的时代,图像处理技术在各个领域都占据着举足轻重的地位…

SpringBoot实现发邮件功能+邮件内容带模版

发送简单邮件模版邮件 1.pom引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>2.5.13</version></dependency><dependency><groupId&…

npm 报错 unable to resolve dependency tree

如下图&#xff1a; 解决&#xff1a;npm install --legacy-peer-deps 其实提示上有&#xff1a;npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps

【蓝桥杯每日一题】3.17

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x 他们说内存泄漏是bug&#xff0c;我说这是系统在逼我进化成SSR级程序员 OK来吧&#xff0c;不多废话&#xff0c;今天来点有难度的&#xff1a;二进制枚举 二进制枚举&#xff0c;就是…

Linux:冯诺依曼体系结构、操作系统、进程概念(一.初识进程)

文章目录 1.冯诺依曼体系结构总线与数据传输通路为什么有内存这个部分计算机存储结构 2.操作系统(Operator System)2.1 概念2.2 设计OS的目的2.3 理解“管理”先描述再组织 2.4 用户使用系统调用和库函数&#xff08;lib&#xff09;概念 总结 3.初识进程3.1 基本事实与引入3.2…

动手学深度学习:CNN和LeNet

前言 该篇文章记述从零如何实现CNN&#xff0c;以及LeNet对于之前数据集分类的提升效果。 从零实现卷积核 import torch def conv2d(X,k):h,wk.shapeYtorch.zeros((X.shape[0]-h1,X.shape[1]-w1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i,j](X[i:ih,j:jw…

删除排序链表中的重复元素(js实现,LeetCode:83)

看到这道题的第一反应是使用快慢指针&#xff0c;之前做过类似的题&#xff1a;删除有序数组中的重复项&#xff08;js实现&#xff0c;LeetCode&#xff1a;26&#xff09;原理都是一样,区别是这题需要将重复项删除&#xff0c;所以只需要走一遍单循环就可以实现 /*** Defini…

单片机自学总结

自从工作以来&#xff0c;一直努力耕耘单片机&#xff0c;至今&#xff0c;颇有收获。从51单片机&#xff0c;PIC单片机&#xff0c;直到STM32&#xff0c;以及RTOS和Linux&#xff0c;几乎天天在搞:51单片机&#xff0c;STM8S207单片机&#xff0c;PY32F003单片机&#xff0c;…

Unity教程(二十二)技能系统 分身技能

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程&#xff08;零&#xff09;Unity和VS的使用相关内容 Unity教程&#xff08;一&#xff09;开始学习状态机 Unity教程&#xff08;二&#xff09;角色移动的实现 Unity教程&#xff08;三&#xff09;角色跳跃的实现 Unity教程&…

HTML5扫雷游戏开发实战

HTML5扫雷游戏开发实战 这里写目录标题 HTML5扫雷游戏开发实战项目介绍技术栈项目架构1. 游戏界面设计2. 核心类设计 核心功能实现1. 游戏初始化2. 地雷布置算法3. 数字计算逻辑4. 扫雷功能实现 性能优化1. DOM操作优化2. 算法优化 项目亮点技术难点突破1. 首次点击保护2. 连锁…

【Git学习笔记】Git分支管理策略及其结构原理分析

【Git学习笔记】Git分支管理策略及其结构原理分析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;Git学习笔记 文章目录 【Git学习笔记】Git分支管理策略及其结构原理分析前言一.合并冲突二. 分支管理策略2.1 分支策略2.2 bug分支2.3 删除临…

Spring Cloud Alibaba Nacos 2023.X 配置问题

文章目录 问题现象&#xff08;一&#xff09;解决方法&#xff08;一&#xff09;问题现象&#xff08;二&#xff09;解决方法&#xff08;二&#xff09;问题现象&#xff08;三&#xff09;解决方法&#xff08;三&#xff09; 问题现象&#xff08;一&#xff09; Spring…

厨卫行业供应链产销协同前中后大平台现状需求分析报告+P120(120页PPT)(文末有下载方式)

资料解读&#xff1a;厨卫行业供应链产销协同前中后大平台现状需求分析报告 详细资料请看本解读文章的最后内容。在当前厨卫行业竞争激烈的市场环境下&#xff0c;企业的发展战略和业务模式创新至关重要。本次解读的报告围绕某厨卫企业展开&#xff0c;深入探讨其供应链产销协同…

我在哪,要去哪

在直播间听到一首好听的歌《我在哪&#xff0c;要去哪》-汤倩。 遇见的事&#xff1a;21~24号抽调去招生。 感受到的情绪&#xff1a;公假吗&#xff1f;给工作量吗&#xff1f;月工作量不够扣钱吗&#xff1f;报销方便吗&#xff1f;有事情&#xff0c;从来不解决后顾&#x…

SpringBoot-2整合MyBatis以及基本的使用方法

目录 1.引入依赖 2.数据库表的创建 3.数据源的配置 4.编写pojo类 5.编写controller类 6.编写接口 7.编写接口的实现类 8.编写mapper 1.引入依赖 在pom.xml引入依赖 <!-- mysql--><dependency><groupId>com.mysql</groupId><artifac…