Refactor database initialization and remove Alembic migrations
- Removed legacy Alembic migration files and consolidated schema management into a new Pydantic-backed initializer (`scripts/init_db.py`). - Updated `main.py` to ensure the new DB initializer runs on startup, maintaining idempotency. - Adjusted session management in `config/database.py` to prevent DetachedInstanceError. - Introduced new enums in `models/enums.py` for better organization and clarity. - Refactored various models to utilize the new enums, improving code maintainability. - Enhanced middleware to handle JSON validation more robustly, ensuring non-JSON requests do not trigger JSON errors. - Added tests for middleware and enums to ensure expected behavior and consistency. - Updated changelog to reflect significant changes and improvements.
This commit is contained in:
40
main.py
40
main.py
@@ -17,6 +17,7 @@ from routes.reports import router as reports_router
|
||||
from routes.scenarios import router as scenarios_router
|
||||
from monitoring import router as monitoring_router
|
||||
from services.bootstrap import bootstrap_admin, bootstrap_pricing_settings
|
||||
from scripts.init_db import init_db as init_db_script
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -44,6 +45,14 @@ async def ensure_admin_bootstrap() -> None:
|
||||
admin_settings = settings.admin_bootstrap_settings()
|
||||
pricing_metadata = settings.pricing_metadata()
|
||||
try:
|
||||
# Ensure DB schema/types/seeds required for bootstrapping exist.
|
||||
# The initializer is idempotent and safe to run on every startup.
|
||||
try:
|
||||
init_db_script()
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"DB initializer failed; continuing to bootstrap (non-fatal)")
|
||||
|
||||
role_result, admin_result = bootstrap_admin(settings=admin_settings)
|
||||
pricing_result = bootstrap_pricing_settings(metadata=pricing_metadata)
|
||||
logger.info(
|
||||
@@ -54,14 +63,29 @@ async def ensure_admin_bootstrap() -> None:
|
||||
admin_result.password_rotated,
|
||||
admin_result.roles_granted,
|
||||
)
|
||||
logger.info(
|
||||
"Pricing settings bootstrap completed: slug=%s created=%s updated_fields=%s impurity_upserts=%s projects_assigned=%s",
|
||||
pricing_result.seed.settings.slug,
|
||||
pricing_result.seed.created,
|
||||
pricing_result.seed.updated_fields,
|
||||
pricing_result.seed.impurity_upserts,
|
||||
pricing_result.projects_assigned,
|
||||
)
|
||||
# Avoid accessing ORM-managed attributes that may be detached outside
|
||||
# of the UnitOfWork/session scope. Attempt a safe extraction and
|
||||
# fall back to minimal logging if attributes are unavailable.
|
||||
try:
|
||||
seed = pricing_result.seed
|
||||
slug = getattr(seed.settings, "slug", None) if seed and getattr(
|
||||
seed, "settings", None) else None
|
||||
created = getattr(seed, "created", None)
|
||||
updated_fields = getattr(seed, "updated_fields", None)
|
||||
impurity_upserts = getattr(seed, "impurity_upserts", None)
|
||||
logger.info(
|
||||
"Pricing settings bootstrap completed: slug=%s created=%s updated_fields=%s impurity_upserts=%s projects_assigned=%s",
|
||||
slug,
|
||||
created,
|
||||
updated_fields,
|
||||
impurity_upserts,
|
||||
pricing_result.projects_assigned,
|
||||
)
|
||||
except Exception:
|
||||
logger.info(
|
||||
"Pricing settings bootstrap completed (partial): projects_assigned=%s",
|
||||
pricing_result.projects_assigned,
|
||||
)
|
||||
except Exception: # pragma: no cover - defensive logging
|
||||
logger.exception(
|
||||
"Failed to bootstrap administrator or pricing settings")
|
||||
|
||||
Reference in New Issue
Block a user