Fix new services implementation 9
This commit is contained in:
@@ -3,75 +3,18 @@
|
|||||||
Database configuration and session management for Recipe Service
|
Database configuration and session management for Recipe Service
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from shared.database.base import DatabaseManager, create_database_manager
|
||||||
from sqlalchemy.orm import sessionmaker, Session
|
|
||||||
from sqlalchemy.pool import StaticPool
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from typing import Generator
|
|
||||||
|
|
||||||
from .config import settings
|
from .config import settings
|
||||||
|
|
||||||
|
# Create database manager using shared async infrastructure
|
||||||
# Create database engine
|
db_manager = create_database_manager(
|
||||||
engine = create_engine(
|
database_url=settings.DATABASE_URL,
|
||||||
settings.DATABASE_URL,
|
service_name="recipes-service",
|
||||||
poolclass=StaticPool,
|
echo=settings.DEBUG
|
||||||
pool_pre_ping=True,
|
|
||||||
pool_recycle=300,
|
|
||||||
echo=settings.DEBUG,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create session factory
|
# Dependency for FastAPI routes
|
||||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
async def get_db():
|
||||||
|
"""FastAPI dependency to get database session"""
|
||||||
|
async for session in db_manager.get_db():
|
||||||
def get_db() -> Generator[Session, None, None]:
|
yield session
|
||||||
"""
|
|
||||||
Dependency to get database session
|
|
||||||
"""
|
|
||||||
db = SessionLocal()
|
|
||||||
try:
|
|
||||||
yield db
|
|
||||||
finally:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_context() -> Generator[Session, None, None]:
|
|
||||||
"""
|
|
||||||
Context manager for database session
|
|
||||||
"""
|
|
||||||
db = SessionLocal()
|
|
||||||
try:
|
|
||||||
yield db
|
|
||||||
db.commit()
|
|
||||||
except Exception:
|
|
||||||
db.rollback()
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseManager:
|
|
||||||
"""Database management utilities"""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def create_all_tables():
|
|
||||||
"""Create all database tables"""
|
|
||||||
from shared.database.base import Base
|
|
||||||
Base.metadata.create_all(bind=engine)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def drop_all_tables():
|
|
||||||
"""Drop all database tables (for testing)"""
|
|
||||||
from shared.database.base import Base
|
|
||||||
Base.metadata.drop_all(bind=engine)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_session() -> Session:
|
|
||||||
"""Get a new database session"""
|
|
||||||
return SessionLocal()
|
|
||||||
|
|
||||||
|
|
||||||
# Database manager instance
|
|
||||||
db_manager = DatabaseManager()
|
|
||||||
@@ -15,6 +15,8 @@ from contextlib import asynccontextmanager
|
|||||||
from .core.config import settings
|
from .core.config import settings
|
||||||
from .core.database import db_manager
|
from .core.database import db_manager
|
||||||
from .api import recipes, production, ingredients
|
from .api import recipes, production, ingredients
|
||||||
|
# Import models to register them with SQLAlchemy metadata
|
||||||
|
from .models import recipes as recipe_models
|
||||||
|
|
||||||
|
|
||||||
# Configure logging
|
# Configure logging
|
||||||
@@ -33,7 +35,7 @@ async def lifespan(app: FastAPI):
|
|||||||
|
|
||||||
# Create database tables
|
# Create database tables
|
||||||
try:
|
try:
|
||||||
db_manager.create_all_tables()
|
await db_manager.create_tables()
|
||||||
logger.info("Database tables created successfully")
|
logger.info("Database tables created successfully")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to create database tables: {e}")
|
logger.error(f"Failed to create database tables: {e}")
|
||||||
@@ -97,17 +99,14 @@ async def health_check():
|
|||||||
"""Health check endpoint"""
|
"""Health check endpoint"""
|
||||||
try:
|
try:
|
||||||
# Test database connection
|
# Test database connection
|
||||||
db = db_manager.get_session()
|
health_result = await db_manager.health_check()
|
||||||
try:
|
|
||||||
db.execute("SELECT 1")
|
|
||||||
finally:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "healthy",
|
"status": "healthy",
|
||||||
"service": settings.SERVICE_NAME,
|
"service": settings.SERVICE_NAME,
|
||||||
"version": settings.SERVICE_VERSION,
|
"version": settings.SERVICE_VERSION,
|
||||||
"environment": settings.ENVIRONMENT
|
"environment": settings.ENVIRONMENT,
|
||||||
|
"database": health_result
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Health check failed: {e}")
|
logger.error(f"Health check failed: {e}")
|
||||||
|
|||||||
@@ -505,7 +505,11 @@ class AIOnboardingService:
|
|||||||
"description": modifications.get("description") or approval.get("notes", ""),
|
"description": modifications.get("description") or approval.get("notes", ""),
|
||||||
# Optional fields
|
# Optional fields
|
||||||
"brand": modifications.get("brand") or approval.get("suggested_supplier"),
|
"brand": modifications.get("brand") or approval.get("suggested_supplier"),
|
||||||
"is_active": True
|
"is_active": True,
|
||||||
|
# Explicitly set boolean fields to ensure they're not NULL
|
||||||
|
"requires_refrigeration": modifications.get("requires_refrigeration", approval.get("requires_refrigeration", False)),
|
||||||
|
"requires_freezing": modifications.get("requires_freezing", approval.get("requires_freezing", False)),
|
||||||
|
"is_perishable": modifications.get("is_perishable", approval.get("is_perishable", False))
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add optional numeric fields only if they exist
|
# Add optional numeric fields only if they exist
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ async def lifespan(app: FastAPI):
|
|||||||
await init_db()
|
await init_db()
|
||||||
logger.info("Database initialized successfully")
|
logger.info("Database initialized successfully")
|
||||||
|
|
||||||
# Setup metrics
|
|
||||||
setup_metrics_early(app, "suppliers-service")
|
|
||||||
logger.info("Metrics setup completed")
|
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -72,6 +68,12 @@ app.add_middleware(
|
|||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Setup metrics
|
||||||
|
try:
|
||||||
|
setup_metrics_early(app, "suppliers-service")
|
||||||
|
logger.info("Metrics setup completed")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Metrics setup failed", error=str(e))
|
||||||
|
|
||||||
# Setup authentication middleware (commented out - not implemented)
|
# Setup authentication middleware (commented out - not implemented)
|
||||||
# setup_auth_middleware(app)
|
# setup_auth_middleware(app)
|
||||||
|
|||||||
@@ -154,9 +154,15 @@ class DatabaseManager:
|
|||||||
try:
|
try:
|
||||||
target_metadata = metadata or Base.metadata
|
target_metadata = metadata or Base.metadata
|
||||||
async with self.async_engine.begin() as conn:
|
async with self.async_engine.begin() as conn:
|
||||||
await conn.run_sync(target_metadata.create_all)
|
await conn.run_sync(target_metadata.create_all, checkfirst=True)
|
||||||
logger.info("Database tables created successfully", service=self.service_name)
|
logger.info("Database tables created successfully", service=self.service_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# Check if it's a "relation already exists" error which can be safely ignored
|
||||||
|
error_str = str(e).lower()
|
||||||
|
if "already exists" in error_str or "duplicate" in error_str:
|
||||||
|
logger.warning(f"Some database objects already exist - continuing: {e}", service=self.service_name)
|
||||||
|
logger.info("Database tables creation completed (some already existed)", service=self.service_name)
|
||||||
|
else:
|
||||||
logger.error(f"Failed to create tables: {e}", service=self.service_name)
|
logger.error(f"Failed to create tables: {e}", service=self.service_name)
|
||||||
raise DatabaseError(f"Table creation failed: {str(e)}")
|
raise DatabaseError(f"Table creation failed: {str(e)}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user