updated docs

This commit is contained in:
2025-01-22 21:46:11 +03:00
parent 87e5f5ab06
commit 1ba2694a9d
50 changed files with 3342 additions and 401 deletions

View File

@@ -7,10 +7,12 @@ This module provides MongoDB connection management with:
3. Error handling
"""
from typing import Optional, Dict, Any, List, Union
from typing import Optional, Dict, Any, List, Union, Callable
from contextlib import contextmanager
from pymongo import MongoClient
from pymongo.results import InsertOneResult, DeleteResult, UpdateResult
from pymongo.cursor import Cursor
from functools import wraps
from AllConfigs.NoSqlDatabase.configs import MongoConfig
@@ -96,39 +98,44 @@ class MongoDBHandler(
def __init__(self):
"""Initialize MongoDB connection if not already initialized."""
if not self._client:
# Build connection URL based on whether credentials are provided
if MongoConfig.USER_NAME and MongoConfig.PASSWORD:
connection_url = (
f"mongodb://{MongoConfig.USER_NAME}:{MongoConfig.PASSWORD}"
f"@{MongoConfig.HOST}:{MongoConfig.PORT}"
)
else:
connection_url = f"mongodb://{MongoConfig.HOST}:{MongoConfig.PORT}"
# Build connection options
connection_kwargs = {
"host": connection_url,
"host": MongoConfig.URL,
"maxPoolSize": 50, # Maximum number of connections in the pool
"minPoolSize": 10, # Minimum number of connections in the pool
"maxIdleTimeMS": 30000, # Maximum time a connection can be idle (30 seconds)
"waitQueueTimeoutMS": 2000, # How long a thread will wait for a connection
"serverSelectionTimeoutMS": 5000, # How long to wait for server selection
}
self._client = MongoClient(**connection_kwargs)
# Test connection
self._client.admin.command("ping")
def __enter__(self):
"""Context manager entry point."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit point - ensures connection is properly closed."""
try:
if self._client:
self._client.close()
self._client = None
except Exception:
# Silently pass any errors during shutdown
pass
return False # Don't suppress any exceptions
def close(self):
"""Close MongoDB connection."""
if self._client:
self._client.close()
self._client = None
def __del__(self):
"""Ensure connection is closed on deletion."""
self.close()
try:
if self._client:
self._client.close()
self._client = None
except Exception:
# Silently pass any errors during shutdown
pass
@property
def client(self) -> MongoClient:
@@ -145,6 +152,41 @@ class MongoDBHandler(
database = self.get_database(database_name)
return database[collection_name]
# Create a function to get the singleton instance
@classmethod
@contextmanager
def get_mongodb(cls):
"""Get or create the MongoDB singleton instance as a context manager."""
instance = cls()
try:
yield instance
finally:
try:
if instance._client:
instance._client.close()
instance._client = None
except Exception:
# Silently pass any errors during shutdown
pass
# Create a singleton instance
@classmethod
def with_mongodb(cls, func: Callable):
"""Decorator to automatically handle MongoDB connection context.
Usage:
@MongoDBHandler.with_mongodb
def my_function(db, *args, **kwargs):
# db is the MongoDB instance
pass
"""
@wraps(func)
def wrapper(*args, **kwargs):
with cls.get_mongodb() as db:
return func(db, *args, **kwargs)
return wrapper
# Create a singleton instance for backward compatibility
mongodb = MongoDBHandler()

View File

@@ -5,25 +5,28 @@ This module provides practical examples of using MongoDB operations through our
Each example demonstrates different aspects of CRUD operations and aggregation.
"""
from typing import Dict, List, Any
import arrow
from datetime import datetime
from Services.MongoDb.database import mongodb
from Services.MongoDb.database import MongoDBHandler
def insert_examples() -> None:
@MongoDBHandler.with_mongodb
def insert_examples(db) -> None:
"""Examples of insert operations."""
# Get the collection
users_collection = db.get_collection("users")
products_collection = db.get_collection("products")
# Single document insert
user_doc = {
"username": "john_doe",
"email": "john@example.com",
"age": 30,
"created_at": datetime.utcnow(),
"created_at": datetime.now(),
}
user_id = mongodb.insert_one(
database="user_db", collection="users", document=user_doc
)
print(f"Inserted user with ID: {user_id}")
result = users_collection.insert_one(user_doc)
print(f"Inserted user with ID: {result.inserted_id}")
# Multiple documents insert
products = [
@@ -31,80 +34,68 @@ def insert_examples() -> None:
{"name": "Mouse", "price": 29.99, "stock": 100},
{"name": "Keyboard", "price": 59.99, "stock": 75},
]
product_ids = mongodb.insert_many(
database="store_db", collection="products", documents=products
)
print(f"Inserted {len(product_ids)} products")
result = products_collection.insert_many(products)
print(f"Inserted {len(result.inserted_ids)} products")
def find_examples() -> None:
@MongoDBHandler.with_mongodb
def find_examples(db) -> None:
"""Examples of find operations."""
# Get the collections
users_collection = db.get_collection("users")
products_collection = db.get_collection("products")
# Find one document
user = mongodb.find_one(
database="user_db",
collection="users",
filter_query={"email": "john@example.com"},
projection={"username": 1, "email": 1, "_id": 0},
)
user = users_collection.find_one({"email": "john@example.com"})
print(f"Found user: {user}")
# Find many with pagination
page_size = 10
page_number = 1
products = mongodb.find_many(
database="store_db",
collection="products",
filter_query={"price": {"$lt": 100}},
projection={"name": 1, "price": 1},
sort=[("price", 1)], # Sort by price ascending
limit=page_size,
skip=(page_number - 1) * page_size,
)
# Find many documents
products_cursor = products_collection.find({"price": {"$lt": 100}})
products = list(products_cursor)
print(f"Found {len(products)} products under $100")
def update_examples() -> None:
@MongoDBHandler.with_mongodb
def update_examples(db) -> None:
"""Examples of update operations."""
# Get the collections
products_collection = db.get_collection("products")
# Update single document
result = mongodb.update_one(
database="store_db",
collection="products",
filter_query={"name": "Laptop"},
update_data={"price": 899.99, "stock": 45},
upsert=False,
result = products_collection.update_one(
{"name": "Laptop"}, {"$set": {"price": 899.99, "stock": 45}}
)
print(f"Updated {result['modified_count']} laptop(s)")
print(f"Updated {result.modified_count} laptop(s)")
# Update multiple documents
result = mongodb.update_many(
database="store_db",
collection="products",
filter_query={"stock": {"$lt": 10}},
update_data={"status": "low_stock"},
upsert=True,
result = products_collection.update_many(
{"stock": {"$lt": 10}}, {"$set": {"status": "low_stock"}}
)
print(f"Updated {result['modified_count']} low stock products")
print(f"Updated {result.modified_count} low stock products")
def delete_examples() -> None:
@MongoDBHandler.with_mongodb
def delete_examples(db) -> None:
"""Examples of delete operations."""
# Get the collections
users_collection = db.get_collection("users")
products_collection = db.get_collection("products")
# Delete single document
count = mongodb.delete_one(
database="user_db",
collection="users",
filter_query={"email": "john@example.com"},
)
print(f"Deleted {count} user")
result = users_collection.delete_one({"email": "john@example.com"})
print(f"Deleted {result.deleted_count} user")
# Delete multiple documents
count = mongodb.delete_many(
database="store_db", collection="products", filter_query={"stock": 0}
)
print(f"Deleted {count} out-of-stock products")
result = products_collection.delete_many({"stock": 0})
print(f"Deleted {result.deleted_count} out-of-stock products")
def aggregate_examples() -> None:
"""Examples of aggregation operations."""
@MongoDBHandler.with_mongodb
def aggregate_examples(db) -> None:
"""Examples of aggregate operations."""
# Get the collection
products_collection = db.get_collection("products")
# Calculate average price by category
pipeline = [
{
@@ -116,21 +107,23 @@ def aggregate_examples() -> None:
},
{"$sort": {"avg_price": -1}},
]
results = mongodb.aggregate(
database="store_db", collection="products", pipeline=pipeline
)
results = products_collection.aggregate(pipeline)
print("Category statistics:", list(results))
def complex_query_example() -> None:
"""Example of a complex query combining multiple operations."""
@MongoDBHandler.with_mongodb
def complex_query_example(db) -> None:
"""Example of a more complex query combining multiple operations."""
# Get the collection
users_collection = db.get_collection("users")
# Find active users who made purchases in last 30 days
pipeline = [
{
"$match": {
"status": "active",
"last_purchase": {
"$gte": datetime.utcnow().replace(day=datetime.utcnow().day - 30)
"$gte": arrow.now().shift(days=-30).datetime,
},
}
},
@@ -152,9 +145,7 @@ def complex_query_example() -> None:
},
{"$sort": {"total_spent": -1}},
]
results = mongodb.aggregate(
database="user_db", collection="users", pipeline=pipeline
)
results = users_collection.aggregate(pipeline)
print("Active users with recent purchases:", list(results))