95 lines
3.8 KiB
Python
95 lines
3.8 KiB
Python
"""
|
|
Database connection management for MongoDB
|
|
Infrastructure Layer - handles low-level database connectivity
|
|
"""
|
|
import os
|
|
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
|
|
from pymongo import IndexModel, ASCENDING, DESCENDING
|
|
from typing import Optional
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class DatabaseConnection:
|
|
"""Manages MongoDB connection and database operations"""
|
|
|
|
def __init__(self):
|
|
self.client: Optional[AsyncIOMotorClient] = None
|
|
self.database: Optional[AsyncIOMotorDatabase] = None
|
|
self._mongodb_url = os.getenv("MONGODB_URL", "mongodb://localhost:27017")
|
|
self._database_name = os.getenv("DATABASE_NAME", "energy_monitoring")
|
|
|
|
async def connect(self) -> None:
|
|
"""Establish connection to MongoDB"""
|
|
try:
|
|
logger.info(f"Connecting to MongoDB at: {self._mongodb_url}")
|
|
|
|
self.client = AsyncIOMotorClient(self._mongodb_url)
|
|
await self.client.admin.command('ping')
|
|
|
|
self.database = self.client[self._database_name]
|
|
await self._create_indexes()
|
|
|
|
logger.info("Successfully connected to MongoDB")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error connecting to MongoDB: {e}")
|
|
raise
|
|
|
|
async def disconnect(self) -> None:
|
|
"""Close MongoDB connection"""
|
|
if self.client:
|
|
self.client.close()
|
|
logger.info("Disconnected from MongoDB")
|
|
|
|
async def get_database(self) -> AsyncIOMotorDatabase:
|
|
"""Get database instance"""
|
|
if not self.database:
|
|
await self.connect()
|
|
return self.database
|
|
|
|
async def _create_indexes(self) -> None:
|
|
"""Create database indexes for optimal performance"""
|
|
try:
|
|
# Sensor readings collection indexes
|
|
sensor_readings_indexes = [
|
|
IndexModel([("sensor_id", ASCENDING), ("timestamp", DESCENDING)]),
|
|
IndexModel([("timestamp", DESCENDING)]),
|
|
IndexModel([("room", ASCENDING), ("timestamp", DESCENDING)]),
|
|
IndexModel([("sensor_type", ASCENDING), ("timestamp", DESCENDING)]),
|
|
IndexModel([("created_at", DESCENDING)]),
|
|
]
|
|
await self.database.sensor_readings.create_indexes(sensor_readings_indexes)
|
|
|
|
# Room metrics collection indexes
|
|
room_metrics_indexes = [
|
|
IndexModel([("room", ASCENDING), ("timestamp", DESCENDING)]),
|
|
IndexModel([("timestamp", DESCENDING)]),
|
|
IndexModel([("created_at", DESCENDING)]),
|
|
]
|
|
await self.database.room_metrics.create_indexes(room_metrics_indexes)
|
|
|
|
# Sensor metadata collection indexes
|
|
sensor_metadata_indexes = [
|
|
IndexModel([("sensor_id", ASCENDING)], unique=True),
|
|
IndexModel([("room", ASCENDING)]),
|
|
IndexModel([("sensor_type", ASCENDING)]),
|
|
IndexModel([("status", ASCENDING)]),
|
|
]
|
|
await self.database.sensor_metadata.create_indexes(sensor_metadata_indexes)
|
|
|
|
# System events collection indexes
|
|
system_events_indexes = [
|
|
IndexModel([("timestamp", DESCENDING)]),
|
|
IndexModel([("event_type", ASCENDING), ("timestamp", DESCENDING)]),
|
|
IndexModel([("severity", ASCENDING), ("timestamp", DESCENDING)]),
|
|
]
|
|
await self.database.system_events.create_indexes(system_events_indexes)
|
|
|
|
logger.info("Database indexes created successfully")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error creating indexes: {e}")
|
|
|
|
# Global database connection instance
|
|
database_connection = DatabaseConnection() |