import logging from typing import AsyncGenerator from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase from pymongo import ASCENDING, IndexModel from app.core.config import settings logger = logging.getLogger("hogar_planeta_tierra") _client: AsyncIOMotorClient | None = None _db: AsyncIOMotorDatabase | None = None async def connect_to_mongo() -> None: global _client, _db logger.info("Conectando a MongoDB...") _client = AsyncIOMotorClient(settings.MONGODB_URI) _db = _client[settings.MONGODB_DB_NAME] await _ensure_indexes(_db) logger.info("MongoDB conectado correctamente") async def close_mongo_connection() -> None: global _client if _client is not None: _client.close() logger.info("Conexión MongoDB cerrada") def get_db() -> AsyncIOMotorDatabase: if _db is None: raise RuntimeError("Base de datos no inicializada") return _db async def get_database() -> AsyncGenerator[AsyncIOMotorDatabase, None]: yield get_db() async def _ensure_indexes(db: AsyncIOMotorDatabase) -> None: # usuarios await db["usuarios"].create_indexes([ IndexModel([("username", ASCENDING)], unique=True), ]) # continentes await db["continentes"].create_indexes([ IndexModel([("nombre", ASCENDING)], unique=True), ]) # conversation_states — TTL 600 s await db["conversation_states"].create_indexes([ IndexModel([("psid", ASCENDING)], unique=True), IndexModel([("created_at", ASCENDING)], expireAfterSeconds=600), ]) # llaves — TTL por expires_at await db["llaves"].create_indexes([ IndexModel([("expires_at", ASCENDING)], expireAfterSeconds=0), IndexModel([("usuario_id", ASCENDING)]), ]) # processed_mids — deduplicación de mensajes Facebook, TTL 1 hora await db["processed_mids"].create_indexes([ IndexModel([("mid", ASCENDING)], unique=True), IndexModel([("created_at", ASCENDING)], expireAfterSeconds=3600), ]) # colecciones geográficas await db["paises"].create_indexes([ IndexModel([("continente_id", ASCENDING)]), IndexModel([("codigo_iso2", ASCENDING)]), ]) await db["estados"].create_indexes([ IndexModel([("pais_id", ASCENDING)]), ]) await db["ciudades"].create_indexes([ IndexModel([("estado_id", ASCENDING)]), IndexModel([("pais_id", ASCENDING)]), ]) # colecciones de datos de ciudad for col in ( "fauna", "flora", "microbiota", "ecosistema", "clima", "gastronomia", "moneda", "idioma", "uso_horario", "ubicacion", ): await db[col].create_indexes([ IndexModel([("ciudad_id", ASCENDING)]), ])