I use the following code in db.py to apply a singleton pattern for providing a MongoClient in my application.
When I call one of the methods in my model like create() or readList() vscode shows the following pymongo threads in my call stack. The threads stay in the call stack during the application lifecycle. When I call create() or readList() n times, the amount of threads stays the same. Is this a normal behaviour? I expected that the threads are closed after some time.
screenshot of pymongo threads in Visual Studio Code
The amount of open threads in vs code while using MongoClient confuses me. What is the "normal" behaviour of pymongo regarding the amount of open threads during the application lifecycle?
# db.py
# Python packages
import sys
# External packages
from pymongo import MongoClient
import importlib.util
# custom packages
spec = importlib.util.spec_from_file_location("utils.config", "../utils/config.py")
config = importlib.util.module_from_spec(spec)
sys.modules["evolveaiUtils.config"] = config
spec.loader.exec_module(config)
def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Db:
db = None
client = None
def __init__(self):
self.client = MongoClient(config.Config.MONGO_URI)
self.db = self.client[config.Config.MONGO_DB_NAME]
def getDb(self):
return self.db
# end of db.py
In my data model classes I use db.py like follows:
# model.py
# Python packages
import sys
# External packages
from bson import ObjectId
from pymongo import ReturnDocument
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
import importlib.util
# custom packages
dbSpec = importlib.util.spec_from_file_location("dal.db", "../dal/db.py")
db = importlib.util.module_from_spec(dbSpec)
sys.modules["dal.db"] = db
dbSpec.loader.exec_module(db)
class SourceEnum(Enum):
WEB = "web"
FILE = "file"
@dataclass
class SourceData:
id: str
title: str
type: str
importDate: datetime
def getDictionary(self):
return self.__dict__
class SourceModel:
"""
Source Model / Data Access Object
The class provides create, read, update and delete methods
for source data stored in a MongoDB
"""
def create(self, data: SourceData) -> SourceData:
result = db.Db().getDb().sources.insert_one(data.getDictionary())
insertedId = str(result.inserted_id)
data.id = insertedId
return data
def readList(self) -> list[SourceData]:
sourceDataList = []
cursor = db.Db().getDb().sources.find({})
for document in cursor:
sourceData = SourceData(
id=str(document['_id']),
title=document['title'],
type=document['type'],
importDate=document['importDate']
)
sourceDataList.append(sourceData)
cursor = None
return sourceDataList
def delete(self, id: str) -> bool:
_id = ObjectId(id)
result = db.Db().getDb().sources.delete_one({"_id": _id})
return result.deleted_count > 0
# end of model.py