"""Celery task: еженедельная синхронизация OSM инженерных сетей для site-finder (#1746).""" import logging from sqlalchemy import text from app.workers.celery_app import celery_app logger = logging.getLogger(__name__) def _log_breadcrumb(level: str, message: str) -> None: """Записать строку в nspd_geo_log (job_id=NULL, stage='utility_sync'). Persistent breadcrumb для диагностики без SSH (как poi_sync / noise_sync). """ try: from app.core.db import SessionLocal db = SessionLocal() try: db.execute( text( "INSERT INTO nspd_geo_log (job_id, level, stage, message) " "VALUES (NULL, :lvl, 'utility_sync', :msg)" ), {"lvl": level, "msg": message[:500]}, ) db.commit() finally: db.close() except Exception as e: logger.warning("utility_sync breadcrumb failed: %s", e) @celery_app.task( name="tasks.utility_infrastructure_sync.sync_osm_utility_infrastructure_ekb", queue="celery", ) def sync_osm_utility_infrastructure_ekb() -> dict: """Еженедельная синхронизация OSM инж.сетей из Overpass в osm_utility_infrastructure_ekb. Запускается через beat (понедельник 04:00 МСК — через 30 мин после noise-sync). No-B2B open-data источник (Overpass). Persistent breadcrumbs в nspd_geo_log. """ _log_breadcrumb("info", "task started") try: from app.services.site_finder.utility_infrastructure_loader import ( sync_utility_infrastructure_to_db, ) result = sync_utility_infrastructure_to_db() logger.info("utility_sync done: %s", result) _log_breadcrumb("info", f"done: {result}") return result except Exception as e: logger.exception("utility_sync failed: %s", e) _log_breadcrumb("error", f"{type(e).__name__}: {e}") raise