No-B2B open-data путь (Overpass) для инженерных сетей ЕКБ: ЛЭП/подстанции/
опоры, трубопроводы (газ/вода/канализация), ЦТП, вышки связи.
- Миграция 100_osm_utility_infrastructure_ekb.sql: таблица + GIST-индекс,
UNIQUE(osm_type, osm_id) для идемпотентного UPSERT, geom(Geometry,4326)
(линии И точки).
- Loader utility_infrastructure_loader.py: Overpass-запросы (rate-limit 1 req/s),
классификация в infrastructure_kind (power/water/gas/heat/communication/sewage),
per-element SAVEPOINT UPSERT. Зеркалит noise_loader (геом-хелперы переиспользованы).
- Celery task + weekly beat (понедельник 04:00 МСК, после noise-sync).
- Endpoint GET /api/v1/parcels/{cad}/utility-infrastructure: инж.сети в радиусе
центроида участка (ST_DWithin) + summary по видам сети. Зеркалит connection-points.
- Тесты: loader (Overpass-парсинг/UPSERT/SAVEPOINT/фильтры) + endpoint (mock DB).
- Codegen: api-types.ts регенерирован (новый endpoint + 3 схемы).
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""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
|