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()
详细解释
-
导入依赖模块
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",那么代码会使用这个地址来连接数据库。
- 作用:导入
-
定义 MongoDatabaseConnector 类
class MongoDatabaseConnector:_instance: MongoClient | None = None- 作用:定义一个类
MongoDatabaseConnector,用来管理 MongoDB 的连接。这里使用了一个类变量_instance来存储连接实例。 - 解释:
_instance初始值为None,表示当前还没有创建数据库连接。类型提示MongoClient | None表示这个变量可能是一个MongoClient对象,也可能是None。
- 作用:定义一个类
-
重写 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(),最终返回的都是同一个连接实例。
- 作用:返回创建好的 MongoClient 实例。这样,无论何时调用
-
-
-
创建连接实例
connection = MongoDatabaseConnector()- 作用:调用
MongoDatabaseConnector()来获取 MongoDB 的连接实例。 - 解释:这行代码实际上会触发上面定义的
__new__方法,判断是否需要创建新连接或直接返回已有连接。最终,变量connection存储了一个MongoClient对象。 - 举例:如果第一次调用时创建连接,则
connection可能代表一个连接到"mongodb://192.168.1.100:27017"的 MongoClient 实例;后续再调用时将复用这个实例。
- 作用:调用
总结
- 单例模式:该代码使用了单例模式保证整个程序中只会创建一个数据库连接。这样可以避免重复创建连接资源,提升效率。
- 错误处理:使用
try...except捕获连接失败的情况,并通过日志记录错误信息,然后抛出异常,确保问题不会被忽略。 - 日志记录:通过
loguru的logger对象,详细记录了连接的成功与失败状态,方便排查问题。 - 实际场景举例:
假设你的数据库地址为"mongodb://192.168.1.100:27017",第一次执行MongoDatabaseConnector()时:- 程序检查
_instance是None; - 连接成功后,将
MongoClient("mongodb://192.168.1.100:27017")赋值给_instance; - 输出日志 “Connection to MongoDB with URI successful: mongodb://192.168.1.100:27017”;
- 将该连接实例返回并赋值给
connection。
如果之后再调用MongoDatabaseConnector(),程序就直接返回已存在的连接实例,不再重新连接。
- 程序检查
这样写的好处是节省资源、简化连接管理,同时通过日志记录帮助开发者快速定位数据库连接的问题。
相关文章:
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,…...
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 系列模型,这里我们一起…...
解决 开发FFMPEG视频播放器右侧白色线问题
在开发基于 Qt 和 FFmpeg 的视频播放器时,我遇到一个常见但令人困惑的问题:在使用 VideoWidget(继承自 QOpenGLWidget)播放某些视频时,窗口右侧会出现一条白色线。这不仅影响视觉效果,还可能暴露潜在的渲染或缓冲区问题。本文将详细分析这一现象的成因,并提供经过验证的…...
解决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
如下图: 解决:npm install --legacy-peer-deps 其实提示上有:npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force, or --legacy-peer-deps...
【蓝桥杯每日一题】3.17
🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x 他们说内存泄漏是bug,我说这是系统在逼我进化成SSR级程序员 OK来吧,不多废话,今天来点有难度的:二进制枚举 二进制枚举,就是…...
leetcode刷题之-整数反转
又开始刷题了,最近在刷这题 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号…...
Linux:冯诺依曼体系结构、操作系统、进程概念(一.初识进程)
文章目录 1.冯诺依曼体系结构总线与数据传输通路为什么有内存这个部分计算机存储结构 2.操作系统(Operator System)2.1 概念2.2 设计OS的目的2.3 理解“管理”先描述再组织 2.4 用户使用系统调用和库函数(lib)概念 总结 3.初识进程3.1 基本事实与引入3.2…...
动手学深度学习:CNN和LeNet
前言 该篇文章记述从零如何实现CNN,以及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…...
C语言 常用系统函数
<string.h> 头文件中的字符串函数 标准库的头文件 <string.h> 中,有三个常用的字符串函数: 函数名 描述 strlen(str) 返回str的长度,类型是 size_t strcpy(str1,str2) 将str2中的字符串复制到str1中 strcat(str1,str2) 将…...
删除排序链表中的重复元素(js实现,LeetCode:83)
看到这道题的第一反应是使用快慢指针,之前做过类似的题:删除有序数组中的重复项(js实现,LeetCode:26)原理都是一样,区别是这题需要将重复项删除,所以只需要走一遍单循环就可以实现 /*** Defini…...
【嵌入式学习】如何利用gitee管理记录学习内容
# 新建git仓库并连接到本地 ## 查看本地是否下载git git --version ## 全局配置git git config --global user.name "你的用户名" git config --global user.email "你的邮箱" git config --global credential.helper store ## 初始化本地仓库 git…...
C#入门学习记录(四)C#运算符详解:掌握算术与条件运算符的必备技巧+字符串拼接
一、运算符概述 运算符是程序进行数学运算、逻辑判断的核心工具,C#中的运算符分为: 算术运算符 → 数学计算( - * / %) 条件运算符 → 三目判断(?:) 关系运算符 → 比较大小(> < &#…...
单片机自学总结
自从工作以来,一直努力耕耘单片机,至今,颇有收获。从51单片机,PIC单片机,直到STM32,以及RTOS和Linux,几乎天天在搞:51单片机,STM8S207单片机,PY32F003单片机,…...
Unity教程(二十二)技能系统 分身技能
Unity开发2D类银河恶魔城游戏学习笔记 Unity教程(零)Unity和VS的使用相关内容 Unity教程(一)开始学习状态机 Unity教程(二)角色移动的实现 Unity教程(三)角色跳跃的实现 Unity教程&…...
HTML5扫雷游戏开发实战
HTML5扫雷游戏开发实战 这里写目录标题 HTML5扫雷游戏开发实战项目介绍技术栈项目架构1. 游戏界面设计2. 核心类设计 核心功能实现1. 游戏初始化2. 地雷布置算法3. 数字计算逻辑4. 扫雷功能实现 性能优化1. DOM操作优化2. 算法优化 项目亮点技术难点突破1. 首次点击保护2. 连锁…...
【Git学习笔记】Git分支管理策略及其结构原理分析
【Git学习笔记】Git分支管理策略及其结构原理分析 🔥个人主页:大白的编程日记 🔥专栏:Git学习笔记 文章目录 【Git学习笔记】Git分支管理策略及其结构原理分析前言一.合并冲突二. 分支管理策略2.1 分支策略2.2 bug分支2.3 删除临…...
Spring Cloud Alibaba Nacos 2023.X 配置问题
文章目录 问题现象(一)解决方法(一)问题现象(二)解决方法(二)问题现象(三)解决方法(三) 问题现象(一) Spring…...
厨卫行业供应链产销协同前中后大平台现状需求分析报告+P120(120页PPT)(文末有下载方式)
资料解读:厨卫行业供应链产销协同前中后大平台现状需求分析报告 详细资料请看本解读文章的最后内容。在当前厨卫行业竞争激烈的市场环境下,企业的发展战略和业务模式创新至关重要。本次解读的报告围绕某厨卫企业展开,深入探讨其供应链产销协同…...
我在哪,要去哪
在直播间听到一首好听的歌《我在哪,要去哪》-汤倩。 遇见的事:21~24号抽调去招生。 感受到的情绪:公假吗?给工作量吗?月工作量不够扣钱吗?报销方便吗?有事情,从来不解决后顾&#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…...
本周安全速报(2025.3.11~3.17)
合规速递 01 瑞士出台新规:关基设施遭遇网络攻击需在24小时内上报 原文: https://www.bleepingcomputer.com/news/security/swiss-critical-sector-faces-new-24-hour-cyberattack-reporting-rule/ 新规要求,关键基础设施组织发现网络攻击后&…...
【css酷炫效果】纯CSS实现瀑布流加载动画
【css酷炫效果】纯CSS实现瀑布流加载动画 缘创作背景html结构css样式完整代码基础版进阶版(无限往复加载) 效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90492012 缘 创作随缘,不定时更新。 创作…...
咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)
✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 随着社会的快速发展和…...
网络编程套接字【端口号/TCPUDP/网络字节序/socket编程接口/UDPTCP网络实验】
网络编程套接字 0. 前言1. 认识端口号2. 认识TCP和UDP协议3. 网络字节序4. socket编程接口5. 实现一个简单的UDP网络程序5.1 需求分析5.2 头文件准备5.3 服务器端设计5.4 客户端设计5.5 本地测试5.6 跨网络测试5.7 UDP小应用——客户端输入命令,服务器端执行 6. 地址…...
