juribot-backend / db /mongoDB.py
entidi2608's picture
update: check file uploaded
d3e9dc7
# db/mongoDB.py
import logging
from typing import Optional
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase, AsyncIOMotorCollection
from pymongo.errors import ConnectionFailure, ConfigurationError
import config # Import từ file config tập trung
logger = logging.getLogger(__name__)
class MongoDatabase:
"""
Một lớp singleton để quản lý kết nối và các collection của MongoDB.
Điều này đảm bảo chúng ta chỉ có một kết nối duy nhất trong toàn bộ ứng dụng.
"""
client: Optional[AsyncIOMotorClient] = None
db: Optional[AsyncIOMotorDatabase] = None
# Khai báo các collection bạn sẽ sử dụng
users: Optional[AsyncIOMotorCollection] = None
token_blacklist: Optional[AsyncIOMotorCollection] = None
conversations: Optional[AsyncIOMotorCollection] = None
processed_documents: Optional[AsyncIOMotorCollection] = None
# Tạo một instance duy nhất để import và sử dụng trong toàn bộ ứng dụng
mongo_db = MongoDatabase()
async def connect_to_mongo():
"""
Hàm khởi tạo kết nối đến MongoDB Atlas và gán vào object mongo_db.
Hàm này sẽ được gọi từ lifespan của FastAPI.
"""
if mongo_db.client:
logger.info("✅ MongoDB connection already established.")
return
logger.info(f"🔸 Connecting to MongoDB Atlas...")
if not config.MONGODB_CLOUD_URI or not config.DB_NAME:
logger.error("❌ MONGODB_CLOUD_URI hoặc DB_NAME chưa được thiết lập trong biến môi trường.")
raise ConfigurationError("MONGODB_CLOUD_URI and DB_NAME must be set.")
try:
# 1. Khởi tạo client bất đồng bộ
mongo_db.client = AsyncIOMotorClient(
config.MONGODB_CLOUD_URI,
serverSelectionTimeoutMS=30000 # Thời gian chờ kết nối là 5 giây
)
# 2. Kiểm tra kết nối một cách rõ ràng
await mongo_db.client.admin.command('ping')
# 3. Gán các đối tượng database và collection
mongo_db.db = mongo_db.client[config.DB_NAME]
mongo_db.users = mongo_db.db["users"]
mongo_db.token_blacklist = mongo_db.db["token_blacklist"]
mongo_db.conversations = mongo_db.db["conversations"]
mongo_db.processed_documents = mongo_db.db["processed_documents"]
# 4. Tạo TTL index một cách an toàn
# Lấy danh sách index hiện có
index_info = await mongo_db.token_blacklist.index_information()
if "expires_at_1" not in index_info:
# Chỉ tạo index nếu nó chưa tồn tại
await mongo_db.token_blacklist.create_index("expires_at", expireAfterSeconds=0)
logger.info("🔸 Successfully created TTL index for 'expires_at' in 'token_blacklist'.")
logger.info("✅ MongoDB connection successful and collections are ready.")
except ConnectionFailure as e:
logger.error(f"❌ Failed to connect to MongoDB: Connection Failure. Check your URI and network access rules in Atlas. Error: {e}", exc_info=True)
raise e
except ConfigurationError as e:
logger.error(f"❌ Failed to connect to MongoDB: Configuration Error. Check your connection string format. Error: {e}", exc_info=True)
raise e
except Exception as e:
logger.error(f"❌ An unexpected error occurred while connecting to MongoDB: {e}", exc_info=True)
raise e
async def close_mongo_connection():
"""Hàm đóng kết nối MongoDB khi ứng dụng tắt."""
if mongo_db.client:
mongo_db.client.close()
logger.info("✅ MongoDB connection closed.")