act_number не извлекается ни у одной строки land_reservation — регекс ждёт суффикс областных актов #2982

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

Что не так

act_number пуст у всех 27 строк land_reservation. Это не «у документов нет номера» — номера есть, но регекс требует суффикса, которого у них нет.

# izyatie_ocr.py
_RE_ACT_NUMBER = re.compile(r"№\s*(\d[\d\s]*[\-–—]?\s*(?:ПП|ПА|РП|ПГ|ГП|МО))\b", ...)

Реальные номера в пяти исходных документах (загружены с екатеринбург.рф и распознаны тем же трактом, что использует загрузчик):

документ номер акта-основания
развязка Базовый/Комсомольская/Сибирский тракт Постановление Администрации от 27.05.2022 № 1413
улица Энергостроителей Постановление Администрации от 12.02.2020 № 259
Татищева — Юрия Исламова Постановление Администрации от 24.06.2019 № 1504
Павлодарская — Щербакова Постановление Администрации от 29.09.2015 № 2687
Иркутская — Шаумяна Постановление Администрации от 19.04.2019 № 863

Ни один не оканчивается на ПП/ПА/РП/ПГ/ГП/МО — это формат областных актов (№ 509-ПП), а не постановлений Администрации города. Даже № 746-П из приказа Министерства не подошёл бы: там одна «П», а шаблон требует две.

Почему не чиню заодно с #2981

act_number входит в уникальный ключ таблицы:

-- data/sql/189_land_reservation_nulls_not_distinct.sql
UNIQUE NULLS NOT DISTINCT (cad_num, act_number)

Сейчас все строки имеют act_number IS NULL, поэтому ключ фактически схлопывается до cad_num — именно это и вычистило 297 → 27 строк в #2966. Как только номер начнёт извлекаться, один и тот же участок, попавший в два разных акта, станет двумя строками. Возможно, это и правильно (участок действительно может быть предметом двух постановлений), но это смена смысла таблицы, а не правка регекса. Нужен отдельный разбор:

  • считаем ли мы (участок, акт) или (участок) единицей учёта;
  • что делать с is_active, если по участку два акта разных лет;
  • нужен ли обратный проход по уже загруженным 27 строкам.

Критерий готовности

После правки: у всех строк источника izyatie_ekb_ocr заполнен act_number, и он совпадает с номером из таблицы выше — проверять сквозным прогоном по тем же пяти PDF, а не только юнит-тестом на выдуманной строке.

Найдено при работе над #2981 (там же — исправление act_date, которое брало дату Генплана-2004 вместо даты акта).

Часть эпика #2464.

## Что не так `act_number` пуст у **всех 27 строк** `land_reservation`. Это не «у документов нет номера» — номера есть, но регекс требует суффикса, которого у них нет. ```python # izyatie_ocr.py _RE_ACT_NUMBER = re.compile(r"№\s*(\d[\d\s]*[\-–—]?\s*(?:ПП|ПА|РП|ПГ|ГП|МО))\b", ...) ``` Реальные номера в пяти исходных документах (загружены с екатеринбург.рф и распознаны тем же трактом, что использует загрузчик): | документ | номер акта-основания | |---|---| | развязка Базовый/Комсомольская/Сибирский тракт | Постановление Администрации от 27.05.2022 **№ 1413** | | улица Энергостроителей | Постановление Администрации от 12.02.2020 **№ 259** | | Татищева — Юрия Исламова | Постановление Администрации от 24.06.2019 **№ 1504** | | Павлодарская — Щербакова | Постановление Администрации от 29.09.2015 **№ 2687** | | Иркутская — Шаумяна | Постановление Администрации от 19.04.2019 **№ 863** | Ни один не оканчивается на `ПП/ПА/РП/ПГ/ГП/МО` — это формат областных актов (`№ 509-ПП`), а не постановлений Администрации города. Даже `№ 746-П` из приказа Министерства не подошёл бы: там одна «П», а шаблон требует две. ## Почему не чиню заодно с #2981 `act_number` входит в уникальный ключ таблицы: ```sql -- data/sql/189_land_reservation_nulls_not_distinct.sql UNIQUE NULLS NOT DISTINCT (cad_num, act_number) ``` Сейчас все строки имеют `act_number IS NULL`, поэтому ключ фактически схлопывается до `cad_num` — именно это и вычистило 297 → 27 строк в #2966. Как только номер начнёт извлекаться, один и тот же участок, попавший в **два разных** акта, станет двумя строками. Возможно, это и правильно (участок действительно может быть предметом двух постановлений), но это смена смысла таблицы, а не правка регекса. Нужен отдельный разбор: - считаем ли мы `(участок, акт)` или `(участок)` единицей учёта; - что делать с `is_active`, если по участку два акта разных лет; - нужен ли обратный проход по уже загруженным 27 строкам. ## Критерий готовности После правки: у всех строк источника `izyatie_ekb_ocr` заполнен `act_number`, и он совпадает с номером из таблицы выше — проверять сквозным прогоном по тем же пяти PDF, а не только юнит-тестом на выдуманной строке. Найдено при работе над #2981 (там же — исправление `act_date`, которое брало дату Генплана-2004 вместо даты акта). Часть эпика #2464.
Author
Collaborator

Перепроверка 28.08. Числа тикета держатся один в один.

land_reservation: 27 строк, act_number заполнен у нуля. Все source = izyatie_ekb_ocr, fetched_at максимум 07.06.

Регекс не тронут — backend/app/services/scrapers/izyatie_ocr.py:34-37:

r"№\s*(\d[\d\s]*[\-–—]?\s*(?:ПП|ПА|РП|ПГ|ГП|МО))"

Суффикс обязателен, номер без него не извлекается.

Новое: тот же дефект есть во втором местеbackend/app/services/scrapers/page_reservation_parser.py:34-37. Шаблон там шире, но суффикс тоже обязателен. Чинить нужно оба, иначе правка закроет только половину.

UNIQUE NULLS NOT DISTINCT (cad_num, act_number) в силе, count(DISTINCT cad_num) = 27 — то есть ключ фактически схлопнут до одного cad_num, как и сказано в теле.

**Перепроверка 28.08. Числа тикета держатся один в один.** `land_reservation`: **27 строк, `act_number` заполнен у нуля**. Все `source = izyatie_ekb_ocr`, `fetched_at` максимум 07.06. Регекс не тронут — `backend/app/services/scrapers/izyatie_ocr.py:34-37`: ``` r"№\s*(\d[\d\s]*[\-–—]?\s*(?:ПП|ПА|РП|ПГ|ГП|МО))" ``` Суффикс обязателен, номер без него не извлекается. Новое: **тот же дефект есть во втором месте** — `backend/app/services/scrapers/page_reservation_parser.py:34-37`. Шаблон там шире, но суффикс тоже обязателен. Чинить нужно оба, иначе правка закроет только половину. `UNIQUE NULLS NOT DISTINCT (cad_num, act_number)` в силе, `count(DISTINCT cad_num) = 27` — то есть ключ фактически схлопнут до одного `cad_num`, как и сказано в теле.
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#2982
No description provided.