generated from john/python-template
This commit is contained in:
@@ -24,6 +24,7 @@ from .config import get_settings
|
||||
from .db import create_all
|
||||
from .db import dispose_database_runtime
|
||||
from .db import initialize_database_runtime
|
||||
from .db import normalize_legacy_status_spellings
|
||||
from .services import ServiceBundle
|
||||
from .ui import register_pages
|
||||
from .worker import worker_consumer_lifespan
|
||||
@@ -42,6 +43,7 @@ async def _lifespan(app: FastAPI):
|
||||
|
||||
if settings.should_bootstrap_schema:
|
||||
await create_all(engine=app.state.runtime.engine)
|
||||
await normalize_legacy_status_spellings(engine=app.state.runtime.engine)
|
||||
|
||||
settings.upload_dir.mkdir(parents=True, exist_ok=True)
|
||||
settings.prompt_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from .operations import create_all
|
||||
from .operations import normalize_legacy_status_spellings
|
||||
from .runtime import dispose_database_runtime
|
||||
from .runtime import initialize_database_runtime
|
||||
from .session import session_scope
|
||||
@@ -8,6 +9,7 @@ __all__ = [
|
||||
"create_all",
|
||||
"dispose_database_runtime",
|
||||
"initialize_database_runtime",
|
||||
"normalize_legacy_status_spellings",
|
||||
"session_scope",
|
||||
"transaction_scope",
|
||||
]
|
||||
|
||||
@@ -2,6 +2,8 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from sqlalchemy import inspect as sqlalchemy_inspect
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.ext.asyncio import AsyncEngine
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||
from sqlmodel import SQLModel
|
||||
@@ -10,6 +12,7 @@ from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from .engine import resolve_engine
|
||||
from .models import DocumentType
|
||||
from .models import JobSourceStatus
|
||||
from .models import PersonRole
|
||||
from .registries import BUILT_IN_DOCUMENT_TYPES
|
||||
from .registries import BUILT_IN_PERSON_ROLES
|
||||
@@ -29,6 +32,47 @@ async def create_all(*, engine: AsyncEngine | None = None) -> None:
|
||||
logger.debug("Database schema bootstrap complete for database_url=%s", active_engine.url)
|
||||
|
||||
|
||||
async def normalize_legacy_status_spellings(*, engine: AsyncEngine | None = None) -> int:
|
||||
"""Normalize legacy enum-name spellings to canonical enum values.
|
||||
|
||||
Historical databases may carry ``TRANSCRIBED``/``FAILED``-style enum *names*
|
||||
in ``job_source.status`` or ``execution_attempt.status``. Runtime models
|
||||
expect canonical lowercase values, so stale rows must be normalized before
|
||||
ORM reads.
|
||||
"""
|
||||
active_engine = engine or resolve_engine()
|
||||
if not hasattr(active_engine, "begin"):
|
||||
return 0
|
||||
replacements = {
|
||||
status.name: status.value
|
||||
for status in JobSourceStatus
|
||||
if status.name != status.value
|
||||
}
|
||||
|
||||
def _normalize(sync_connection) -> int:
|
||||
inspector = sqlalchemy_inspect(sync_connection)
|
||||
table_names = set(inspector.get_table_names())
|
||||
if not table_names:
|
||||
return 0
|
||||
fixed = 0
|
||||
for table_name in ("job_source", "execution_attempt"):
|
||||
if table_name not in table_names:
|
||||
continue
|
||||
for legacy, canonical in replacements.items():
|
||||
result = sync_connection.execute(
|
||||
text(f'update "{table_name}" set status = :canonical where status = :legacy'),
|
||||
{"canonical": canonical, "legacy": legacy},
|
||||
)
|
||||
fixed += result.rowcount or 0
|
||||
return fixed
|
||||
|
||||
async with active_engine.begin() as connection:
|
||||
fixed_rows = await connection.run_sync(_normalize)
|
||||
if fixed_rows:
|
||||
logger.warning("Normalized %s legacy status row(s) to canonical spellings", fixed_rows)
|
||||
return fixed_rows
|
||||
|
||||
|
||||
async def seed_registry_defaults(*, engine: AsyncEngine | None = None) -> None:
|
||||
"""Seed default registry rows for role and document type taxonomies."""
|
||||
active_engine = engine or resolve_engine()
|
||||
|
||||
Reference in New Issue
Block a user