feat(mera): загрузчик реестра МКД АИС ФРТ → обогащение houses #3426

Merged
lekss361 merged 1 commit from feat/mera-frt-mkd-loader into main 2026-09-08 21:41:25 +00:00
Owner

Что и зачем

Открытые данные АИС ППК «ФРТ» (бывш. Реформа ЖКХ), opendata/export/110 = реестр МКД региона 66. Анонимный GET, без ЕСИА, ZIP→CSV (UTF-8 BOM, ;).

41 790 строк по СО / 8 117 по ЕКБ, houseguid (ФИАС GUID) заполнен на 100% → join к houses.gar_house_guid без канонизации адреса.

Заполняет только NULL-поля houses (COALESCE-семантика): year_built, material_walls, material_floors, total_floors, entrances, is_emergency, flat_count, heat_supply_type, gas_supply_type, hot_water + новые area_land, foundation_type, elevators_total.

Замер по ЕКБ

поле ФРТ было
wall_material 92.5% 75% (ДОМ.РФ капремонт)
built_year 92.0% 86%
floor_count_max 94.7% частично
area_land 86.8% нет источника
is_emergency 100% (143 дома ЕКБ, 2 897 СО) нет источника

Осознанно НЕ сделано

  • project_typeseries_name — свободный текст и фактически дубль материала стен: пусто у 10 635 строк, «кирпичный» 1754, «нет данных» 1496, «Блочный»/«блочный» двумя разными строками. Как серию использовать нельзя.
  • energy_efficiency — решение миграции 284 + реальный класс лишь у ~10% домов (у 25 595 из 41 790 значение «Не присвоен»).
  • elevators_countpassenger_elevators — в источнике это ОБЩЕЕ число лифтов, в houses раздельно пассажирские и грузовые → отдельная колонка elevators_total.
  • playground/sportsground — в источнике id справочника (498/499/500), не булев флаг.
  • estimator.py не тронут — аналоги подбираются FROM listings без JOIN к houses, встраивание признаков в подбор когорты это отдельная задача.

Найденное на реальных данных

Дубликаты houseguid реальны и взаимодополняющи: 912 guid'ов, 968 лишних строк, причём у одной строки пары заполнен area_total, а у парной нет. Изначальное «последняя побеждает» теряло эти значения. Строки слитые по полям (первое непустое побеждает) — прогон на реальном CSV показал возврат данных: built_year +282 дома, wall_material +226, area_land +226.

Баг is_alarm: голое 'нет' числится мусорным значением текстовых полей, но is_alarm='Нет' — содержательный ответ. Через общий нормализатор все 37 936 неаварийных домов писались бы как NULL, и is_emergency никогда не получал бы false.

Проверка

  • Парсер прогнан на реальном 41 МБ CSV: 40 822 записи после слияния дублей, houseguid 100%, built_year 1853–2022, is_alarm 37 936/2 886.
  • ruff check — чисто; полный сьют pytest5 648 passed, 37 skipped.
  • Миграции 290 (staging frt_mkd + колонки houses) и 291 (сид расписания, enabled=false, interval_days 30).

robots.txt источника запрещает /opendata/export/ и требует Crawl-delay 10 — зафиксировано в докстринге, прогон делает один GET.

## Что и зачем Открытые данные **АИС ППК «ФРТ»** (бывш. Реформа ЖКХ), `opendata/export/110` = реестр МКД региона 66. Анонимный GET, без ЕСИА, ZIP→CSV (UTF-8 BOM, `;`). **41 790 строк по СО / 8 117 по ЕКБ, `houseguid` (ФИАС GUID) заполнен на 100%** → join к `houses.gar_house_guid` без канонизации адреса. Заполняет **только NULL-поля** `houses` (COALESCE-семантика): `year_built`, `material_walls`, `material_floors`, `total_floors`, `entrances`, `is_emergency`, `flat_count`, `heat_supply_type`, `gas_supply_type`, `hot_water` + новые `area_land`, `foundation_type`, `elevators_total`. ### Замер по ЕКБ | поле | ФРТ | было | |---|---|---| | `wall_material` | 92.5% | 75% (ДОМ.РФ капремонт) | | `built_year` | 92.0% | 86% | | `floor_count_max` | 94.7% | частично | | `area_land` | 86.8% | **нет источника** | | `is_emergency` | 100% (143 дома ЕКБ, 2 897 СО) | **нет источника** | ## Осознанно НЕ сделано - **`project_type` → `series_name`** — свободный текст и фактически дубль материала стен: пусто у 10 635 строк, «кирпичный» 1754, «нет данных» 1496, «Блочный»/«блочный» двумя разными строками. Как серию использовать нельзя. - **`energy_efficiency`** — решение миграции 284 + реальный класс лишь у ~10% домов (у 25 595 из 41 790 значение «Не присвоен»). - **`elevators_count` → `passenger_elevators`** — в источнике это ОБЩЕЕ число лифтов, в `houses` раздельно пассажирские и грузовые → отдельная колонка `elevators_total`. - **`playground`/`sportsground`** — в источнике id справочника (498/499/500), не булев флаг. - **`estimator.py` не тронут** — аналоги подбираются `FROM listings` без JOIN к `houses`, встраивание признаков в подбор когорты это отдельная задача. ## Найденное на реальных данных **Дубликаты `houseguid` реальны и взаимодополняющи:** 912 guid'ов, 968 лишних строк, причём у одной строки пары заполнен `area_total`, а у парной нет. Изначальное «последняя побеждает» теряло эти значения. Строки слитые по полям (первое непустое побеждает) — прогон на реальном CSV показал возврат данных: `built_year` +282 дома, `wall_material` +226, `area_land` +226. **Баг `is_alarm`:** голое `'нет'` числится мусорным значением текстовых полей, но `is_alarm='Нет'` — содержательный ответ. Через общий нормализатор все 37 936 неаварийных домов писались бы как NULL, и `is_emergency` никогда не получал бы `false`. ## Проверка - Парсер прогнан на **реальном 41 МБ CSV**: 40 822 записи после слияния дублей, `houseguid` 100%, `built_year` 1853–2022, `is_alarm` 37 936/2 886. - `ruff check` — чисто; полный сьют `pytest` — **5 648 passed, 37 skipped**. - Миграции **290** (staging `frt_mkd` + колонки `houses`) и **291** (сид расписания, `enabled=false`, `interval_days` 30). `robots.txt` источника запрещает `/opendata/export/` и требует `Crawl-delay 10` — зафиксировано в докстринге, прогон делает один GET.
lekss361 added 1 commit 2026-09-08 21:33:44 +00:00
feat(mera): загрузчик реестра МКД АИС ФРТ → обогащение houses
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m14s
8aca820a46
Открытые данные АИС ППК «ФРТ» (бывш. Реформа ЖКХ), node 110 = реестр МКД
региона 66: 41 790 строк, houseguid (ФИАС GUID) заполнен на 100% → join к
houses.gar_house_guid без канонизации адреса. Анонимный GET, без ЕСИА.

Заполняет ТОЛЬКО NULL-поля houses: year_built, material_walls, material_floors,
total_floors, entrances, is_emergency, flat_count, heat_supply_type,
gas_supply_type, hot_water + новые area_land, foundation_type, elevators_total.

Замер по ЕКБ: wall_material 92.5% (было 75% от ДОМ.РФ), built_year 92.0%
(было 86%), area_land 86.8% и is_emergency — признаков, которых не давал
ни один из текущих источников.

Осознанно НЕ мапится:
- project_type → series_name: свободный текст и фактически дубль материала стен
  (пусто у 10 635 строк, «кирпичный» 1754, «нет данных» 1496);
- energy_efficiency: решение миграции 284 + реальный класс лишь у ~10% домов
  (у 25 595 из 41 790 значение «Не присвоен»);
- elevators_count → passenger_elevators: в источнике это ОБЩЕЕ число лифтов,
  в houses раздельно пассажирские и грузовые → отдельная колонка;
- playground/sportsground: в источнике id справочника (498/499/500), не флаг.

Дубликаты houseguid реальны и взаимодополняющи: 912 guid'ов, 968 лишних строк,
у одной строки пары заполнен area_total, у парной нет. Строки СЛИВАЮТСЯ по
полям (первое непустое побеждает), иначе бэкфилл терял бы данные ~2% домов.

estimator.py не тронут: аналоги подбираются FROM listings без JOIN к houses,
встраивание признаков в подбор когорты — отдельная задача.

Миграции 290 (staging frt_mkd + колонки houses) и 291 (сид расписания,
enabled=false, interval_days 30). robots.txt источника требует Crawl-delay 10.
lekss361 merged commit e7ef6bc4a2 into main 2026-09-08 21:41:25 +00:00
lekss361 deleted branch feat/mera-frt-mkd-loader 2026-09-08 21:41:25 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3426
No description provided.