cad_territorial_zones: запрос к НСПД на каждый квартал, 1 строка в таблице и ни одного читателя #2985

Open
opened 2026-08-20 16:54:28 +00:00 by bot-backend · 1 comment
Collaborator

Находка

harvest_quarter (Phase 2.5) делает отдельный запрос к НСПД на каждый кварталget_territorial_zones_in_bbox(quarter_bbox) — и складывает результат в cad_territorial_zones. Эту таблицу не читает никто.

Замер прода 20.08.2026:

cad_territorial_zones          1 строка
  единственная: quarter 66:41:0614005, zone_id 1614620304,
                zone_code = NULL, zone_name = NULL

nspd_quarter_dumps           669 дампов
  territorial_zones_count суммарно  2079   (в 524 кварталах)

Зоны, которые реально доезжают до отчёта, приходят другой трубой: _get_zoning в quarter_dump_lookup.py читает nspd_quarter_dumps.features_json, который пишет nspd_sync.py. bulk_harvest.py в features_json не пишет вовсе.

Поиск по коду читателей cad_territorial_zones даёт только сам писатель (_save_territorial_zones) и две миграции (102_cad_nspd_overlay_tables.sql, 159_alter_cad_territorial_zones_multipolygon.sql).

Почему это стоит внимания

  1. Запрос тратится впустую. НСПД сейчас под WAF-баном и жёстким rate-limit — лишний запрос на квартал идёт в сервис, который и без того отдаёт 403.
  2. Даже единственная строка разобрана неверно. У неё zone_code и zone_name = NULL, хотя код ищет их по шести ключам (zone_code/zone_index/reg_numb_border, zone_name/zone_type_name/type_zone). Значит имена свойств в ответе НСПД другие — маппинг не совпадает с реальностью.
  3. Одна строка на 524 квартала с зонами — сама по себе аномалия. Вероятная причина: вызов падает и глушится except Exception: logger.warning ниже. Это не проверено — в логах контейнера за нужный период я не смотрел, отмечаю как гипотезу, а не факт.

Отсюда — вердикт по пункту эпика #2464

Пункт bulk_harvest.py:1464 (синтетический zone_id = md5(properties), две геометрически разные зоны с одинаковыми свойствами схлопываются через ON CONFLICT (zone_id) DO UPDATE) сегодня безвреден: синтетических id на проде 0 из 1, а таблицу никто не читает. Чинить хеш до того, как решена судьба самой таблицы, — правка ради галочки.

Что решить

Одно из двух, и это решение владельца, а не моё:

  • либо довести трубу до конца: починить маппинг свойств, разобраться с одной строкой, найти потребителя (ПЗЗ-зона в §6 сейчас берётся из features_json — возможно, эта таблица задумывалась как её замена);
  • либо убрать Phase 2.5 целиком вместе с таблицей: это снимет лишний запрос к забаненному НСПД на каждый квартал.

Пока не решено — оставляю как есть и не трогаю хеш.

Критерий проверки, если выберут первый путь

После правки: cad_territorial_zones содержит строки хотя бы для тех 524 кварталов, где territorial_zones_count > 0, и у них заполнены zone_code/zone_name. Сверять с features_json того же квартала, а не с самим собой.

Найдено при разборе пункта bulk_harvest.py:1464 эпика #2464.

## Находка `harvest_quarter` (Phase 2.5) делает **отдельный запрос к НСПД на каждый квартал** — `get_territorial_zones_in_bbox(quarter_bbox)` — и складывает результат в `cad_territorial_zones`. Эту таблицу **не читает никто**. Замер прода 20.08.2026: ``` cad_territorial_zones 1 строка единственная: quarter 66:41:0614005, zone_id 1614620304, zone_code = NULL, zone_name = NULL nspd_quarter_dumps 669 дампов territorial_zones_count суммарно 2079 (в 524 кварталах) ``` Зоны, которые реально доезжают до отчёта, приходят **другой трубой**: `_get_zoning` в `quarter_dump_lookup.py` читает `nspd_quarter_dumps.features_json`, который пишет `nspd_sync.py`. `bulk_harvest.py` в `features_json` не пишет вовсе. Поиск по коду читателей `cad_territorial_zones` даёт только сам писатель (`_save_territorial_zones`) и две миграции (`102_cad_nspd_overlay_tables.sql`, `159_alter_cad_territorial_zones_multipolygon.sql`). ## Почему это стоит внимания 1. **Запрос тратится впустую.** НСПД сейчас под WAF-баном и жёстким rate-limit — лишний запрос на квартал идёт в сервис, который и без того отдаёт 403. 2. **Даже единственная строка разобрана неверно.** У неё `zone_code` и `zone_name` = NULL, хотя код ищет их по шести ключам (`zone_code`/`zone_index`/`reg_numb_border`, `zone_name`/`zone_type_name`/`type_zone`). Значит имена свойств в ответе НСПД другие — маппинг не совпадает с реальностью. 3. **Одна строка на 524 квартала с зонами** — сама по себе аномалия. Вероятная причина: вызов падает и глушится `except Exception: logger.warning` ниже. Это **не проверено** — в логах контейнера за нужный период я не смотрел, отмечаю как гипотезу, а не факт. ## Отсюда — вердикт по пункту эпика #2464 Пункт `bulk_harvest.py:1464` (синтетический `zone_id = md5(properties)`, две геометрически разные зоны с одинаковыми свойствами схлопываются через `ON CONFLICT (zone_id) DO UPDATE`) **сегодня безвреден**: синтетических id на проде **0 из 1**, а таблицу никто не читает. Чинить хеш до того, как решена судьба самой таблицы, — правка ради галочки. ## Что решить Одно из двух, и это решение владельца, а не моё: - **либо** довести трубу до конца: починить маппинг свойств, разобраться с одной строкой, найти потребителя (ПЗЗ-зона в §6 сейчас берётся из `features_json` — возможно, эта таблица задумывалась как её замена); - **либо** убрать Phase 2.5 целиком вместе с таблицей: это снимет лишний запрос к забаненному НСПД на каждый квартал. Пока не решено — оставляю как есть и не трогаю хеш. ## Критерий проверки, если выберут первый путь После правки: `cad_territorial_zones` содержит строки хотя бы для тех 524 кварталов, где `territorial_zones_count > 0`, и у них заполнены `zone_code`/`zone_name`. Сверять с `features_json` того же квартала, а не с самим собой. Найдено при разборе пункта `bulk_harvest.py:1464` эпика #2464.
Author
Collaborator

Перепроверка 28.08 после разблокировки НСПД. Тикет жив — разблокировка его не закрывает.

cad_territorial_zones по-прежнему 1 строка: 66:41:0614005, zone_id 1614620304, zone_code и zone_name пустые, fetched_at = 2026-05-24. Замер тикета от 20.08 совпадает с сегодняшним до строки.

Важное уточнение, снимающее ложную надежду: успешный harvest 27.08 (квартал 66:01:0202002, territorial_zones_count = 6, harvest_error IS NULL) прошёл другой трубой — он пишет nspd_quarter_dumps, а в cad_territorial_zones не добавил ничего. То есть доступ к НСПД восстановился, а эта таблица как не наполнялась, так и не наполняется.

Читателей у таблицы по-прежнему нет: единственное упоминание вне миграций и тестов — писатель _save_territorial_zones (backend/app/services/cadastre/bulk_harvest.py:1482). Запрос на каждый квартал жив (bulk_harvest.py:289-290).

Мелкая правка чисел в теле: tz_sum 2079 → 2019, кварталов с зонами 524 → 509. Дампов 669 — как и было.

Гипотеза тикета про заглушенный except осталась непроверенной: логи воркера на этот счёт не смотрел.

**Перепроверка 28.08 после разблокировки НСПД. Тикет жив — разблокировка его не закрывает.** `cad_territorial_zones` по-прежнему **1 строка**: `66:41:0614005`, `zone_id 1614620304`, `zone_code` и `zone_name` пустые, `fetched_at = 2026-05-24`. Замер тикета от 20.08 совпадает с сегодняшним до строки. Важное уточнение, снимающее ложную надежду: успешный harvest 27.08 (квартал `66:01:0202002`, `territorial_zones_count = 6`, `harvest_error IS NULL`) прошёл **другой трубой** — он пишет `nspd_quarter_dumps`, а в `cad_territorial_zones` не добавил ничего. То есть доступ к НСПД восстановился, а эта таблица как не наполнялась, так и не наполняется. Читателей у таблицы по-прежнему нет: единственное упоминание вне миграций и тестов — писатель `_save_territorial_zones` (`backend/app/services/cadastre/bulk_harvest.py:1482`). Запрос на каждый квартал жив (`bulk_harvest.py:289-290`). Мелкая правка чисел в теле: `tz_sum` 2079 → **2019**, кварталов с зонами 524 → **509**. Дампов 669 — как и было. Гипотеза тикета про заглушенный `except` осталась непроверенной: логи воркера на этот счёт не смотрел.
Sign in to join this conversation.
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#2985
No description provided.