gendesign/tradein-mvp/backend/app/tasks/domrf_kapremont_load.py
bot-backend cc231946c2
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 45s
Deploy Trade-In / build-backend (push) Successful in 1m1s
Deploy Trade-In / deploy (push) Successful in 2m46s
feat(tradein): fill houses.year_built/material_walls from ДОМ.РФ КР1.1/1.2 + zhkh_year, propagate to listings (#2013) (#2476)
2026-07-12 13:12:07 +00:00

124 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""CLI: ДОМ.РФ капремонт open data → houses.year_built/material_walls (issue #2013).
Тянет КР1.1 (house registry) + КР1.2 (constructive elements) с открытых данных
ДОМ.РФ (region 66), UPSERT'ит в staging `domrf_kapremont` (мигр. 176), затем:
1. backfill_houses_from_domrf — COALESCE(houses.year_built, domrf.commission_year,
houses.zhkh_year) + material_walls + total_floors (fold-in уже загруженного
ГИС-ЖКХ года — houses без domrf-матча тоже выигрывают).
2. propagate_listings_year_from_houses — UPDATE listings.year_built = houses.year_built
там, где listing ещё NULL. Именно это открывает estimator'у (year_built BETWEEN
когорта-фильтр) реальные годы на источниках вроде avito (0% year_built, 52.5%
linked к houses).
Запуск из контейнера tradein-backend (у прода есть интернет к домрф.рф):
python -m app.tasks.domrf_kapremont_load # полный прогон
python -m app.tasks.domrf_kapremont_load --dry-run # без записи, только подсчёт
python -m app.tasks.domrf_kapremont_load --load-only # только staging, без backfill
python -m app.tasks.domrf_kapremont_load --backfill-only # staging уже загружена — только
# backfill+propagate
python -m app.tasks.domrf_kapremont_load \\
--kr11-path /tmp/kr11.csv --kr12-path /tmp/kr12.csv # локальные CSV, без скачивания
В режиме --dry-run скачивание/парс (если применимо) происходят, но НИ ОДНОЙ записи
в БД не делается.
"""
from __future__ import annotations
import argparse
import logging
from app.core.db import SessionLocal
from app.services.domrf_kapremont_loader import (
backfill_houses_from_domrf,
load_domrf_kapremont,
propagate_listings_year_from_houses,
)
logger = logging.getLogger(__name__)
def build_parser() -> argparse.ArgumentParser:
"""Парсер CLI (вынесен для тестируемости флагов без запуска main)."""
parser = argparse.ArgumentParser(
description=(
"ДОМ.РФ капремонт loader: КР1.1+КР1.2 → domrf_kapremont staging → "
"houses.year_built/material_walls/total_floors → listings.year_built"
)
)
parser.add_argument(
"--kr11-path", default=None, help="локальный CSV КР1.1 (пропустить скачивание)"
)
parser.add_argument(
"--kr12-path", default=None, help="локальный CSV КР1.2 (пропустить скачивание)"
)
parser.add_argument(
"--work-dir",
default=None,
help="каталог для скачанных/распакованных CSV (по умолчанию — временный, удаляется после)",
)
parser.add_argument(
"--dry-run", action="store_true", help="без записи в БД — только скачивание/парс/подсчёт"
)
parser.add_argument(
"--load-only",
action="store_true",
help="только скачать+распарсить+UPSERT staging, без backfill houses/propagate listings",
)
parser.add_argument(
"--backfill-only",
action="store_true",
help="пропустить скачивание/load staging (считаем что уже загружена этим же "
"или предыдущим прогоном) — только backfill houses + propagate listings",
)
return parser
def main() -> None:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
parser = build_parser()
args = parser.parse_args()
if args.load_only and args.backfill_only:
parser.error("--load-only и --backfill-only взаимоисключающи")
db = SessionLocal()
try:
load_counts: dict[str, int] = {}
if not args.backfill_only:
load_counts = load_domrf_kapremont(
db,
kr11_path=args.kr11_path,
kr12_path=args.kr12_path,
work_dir=args.work_dir,
dry_run=args.dry_run,
)
if not args.dry_run:
db.commit()
logger.info("domrf_kapremont_load: load stage done: %s", load_counts)
houses_counts: dict[str, int] = {}
listings_counts: dict[str, int] = {}
if not args.load_only:
houses_counts = backfill_houses_from_domrf(db, dry_run=args.dry_run)
listings_counts = propagate_listings_year_from_houses(db, dry_run=args.dry_run)
if not args.dry_run:
db.commit()
logger.info(
"domrf_kapremont_load DONE: dry_run=%s load=%s houses=%s listings=%s",
args.dry_run,
load_counts,
houses_counts,
listings_counts,
)
finally:
db.close()
if __name__ == "__main__":
main()