fix(data): партиции rosreestr_deals на Q2–Q4 2026 + загрузчик доходит до файла (#2998) #3014

Merged
bot-backend merged 3 commits from fix/2998-rosreestr-q2-partitions into main 2026-08-21 08:56:25 +00:00
Collaborator

Диагноз задачи был неверным в причине; настоящий корень — структурный

Подробный разбор — в комментарии к #2998. Коротко:

  • Импорт исправен. rosreestr_dkp_import ежедневно вычитывает все 96 974 строки FDW-источника и честно пропускает (rows_fetched = rows_skipped = 96974). total_seen — поле админ-витрины, не счётчик импорта.
  • Источник стоял на Q1 2026 (загружен 30.04). Q2 опубликован 10.07, rosreestr_quarter_poll заметил его 14.08 (available=1), deals_freshness_monitor с 16.08 ставил alert=1 ежедневно. Семь событий в GlitchTip — 0 правил, 0 адресатов, 0 отправок.
  • Корень: rosreestr_deals партиционирована по period_start_date, партиции созданы списком в 01_schema «2024 Q3 — 2026 Q1», и ничто новые не создаёт. Загрузка Q2 21.08 упала:
ERROR:  no partition of relation "rosreestr_deals" found for row
DETAIL:  Partition key of the failing row contains (period_start_date) = (2026-04-01).

Даже оператор, запустив загрузчик по подсказке poll, получил бы отказ.

Что в PR

193_partitions_rosreestr_2026_q2_q4.sql — партиции Q2–Q4 2026 с запасом, IF NOT EXISTS, lock_timeout. Индексы не перечисляю — наследуются от родителя (проверено на проде: 4 на 2026q2).

02_load_all_quarters.sh — две правки:

  1. JOBS дополнен 2026Q2–Q4 (квартал без CSV честно SKIP).
  2. Ловушка set -e: resolve_csv сигналит «файла нет» кодом 1, и первый же квартал без CSV молча ронял весь прогон до строки SKIP. На проде с одним Q2-файлом в data/raw скрипт завершался rc=0, не напечатав ни строки — поймал при боевой проверке. || true на вызове.

test_2998_rosreestr_partition_horizon.py — сторож, чтобы горизонт не отстал снова. Партиция обязана существовать на последний публикуемый квартал (+20 дней лага: Q2 2026 вышел 10.07) и на следующий — иначе предупреждение придёт в день публикации, когда дамп уже лежит и его уже нельзя загрузить.

Как проверено

  • Данные уже на проде, штатным путём: 741 874 строки Q2 в rosreestr_deals (ЕКБ-фильтр 13 654), import-rosreestr.shtradein.deals +11 649, max(deal_date) 2026-01-01 → 2026-04-01. deals_freshness_monitor на следующем тике: alert 0, latest_quarter 2 — цикл замкнулся.
  • Загрузчик боевым путём на VPS после правки: 12 кварталов, 2026Q2 SKIP — уже загружен (741874 строк), остальные SKIP — нет CSV, rc=0. До правки — пустой вывод, rc=0.
  • Сторож двусторонний, и красная сторона воспроизводима на проде, где миграция уже применена: в откатываемой транзакции DETACH PARTITION → головная проверка краснеет по значению («нет партиции на квартал 2026-04-01»), откат возвращает партицию. После теста на проде 12 партиций, 741 874 строки Q2 — цел.
  • Без БД — 4 теста skip с причиной (allowlist), календарный идёт везде.
  • pytest backend/tests/sql55 passed через туннель к проду.

Что остаётся вне PR

  • Доставка алертов — сторожа исправны, адресатов нет. Это #2704 (GlitchTip без правил), не новая работа.
  • Автосоздание партиций — сейчас каждый новый квартал = новая миграция. Запас до конца 2026; в начале декабря сторож покраснеет на Q1 2027, и это правильно.
## Диагноз задачи был неверным в причине; настоящий корень — структурный Подробный разбор — в комментарии к #2998. Коротко: - **Импорт исправен.** `rosreestr_dkp_import` ежедневно вычитывает все 96 974 строки FDW-источника и честно пропускает (`rows_fetched = rows_skipped = 96974`). `total_seen` — поле админ-витрины, не счётчик импорта. - **Источник стоял на Q1 2026** (загружен 30.04). Q2 опубликован 10.07, `rosreestr_quarter_poll` заметил его 14.08 (`available=1`), `deals_freshness_monitor` с 16.08 ставил `alert=1` ежедневно. Семь событий в GlitchTip — **0 правил, 0 адресатов, 0 отправок**. - **Корень:** `rosreestr_deals` партиционирована по `period_start_date`, партиции созданы списком в `01_schema` «2024 Q3 — 2026 Q1», и ничто новые не создаёт. Загрузка Q2 21.08 упала: ``` ERROR: no partition of relation "rosreestr_deals" found for row DETAIL: Partition key of the failing row contains (period_start_date) = (2026-04-01). ``` Даже оператор, запустив загрузчик по подсказке poll, получил бы отказ. ## Что в PR **`193_partitions_rosreestr_2026_q2_q4.sql`** — партиции Q2–Q4 2026 с запасом, `IF NOT EXISTS`, `lock_timeout`. Индексы не перечисляю — наследуются от родителя (проверено на проде: 4 на `2026q2`). **`02_load_all_quarters.sh`** — две правки: 1. `JOBS` дополнен 2026Q2–Q4 (квартал без CSV честно `SKIP`). 2. Ловушка `set -e`: `resolve_csv` сигналит «файла нет» кодом 1, и первый же квартал без CSV **молча ронял весь прогон** до строки `SKIP`. На проде с одним Q2-файлом в `data/raw` скрипт завершался `rc=0`, не напечатав ни строки — поймал при боевой проверке. `|| true` на вызове. **`test_2998_rosreestr_partition_horizon.py`** — сторож, чтобы горизонт не отстал снова. Партиция обязана существовать на последний публикуемый квартал (+20 дней лага: Q2 2026 вышел 10.07) **и на следующий** — иначе предупреждение придёт в день публикации, когда дамп уже лежит и его уже нельзя загрузить. ## Как проверено - **Данные уже на проде, штатным путём:** 741 874 строки Q2 в `rosreestr_deals` (ЕКБ-фильтр 13 654), `import-rosreestr.sh` → `tradein.deals` **+11 649**, `max(deal_date)` 2026-01-01 → **2026-04-01**. `deals_freshness_monitor` на следующем тике: `alert 0, latest_quarter 2` — цикл замкнулся. - **Загрузчик боевым путём на VPS** после правки: 12 кварталов, `2026Q2 SKIP — уже загружен (741874 строк)`, остальные `SKIP — нет CSV`, `rc=0`. До правки — пустой вывод, `rc=0`. - **Сторож двусторонний, и красная сторона воспроизводима на проде**, где миграция уже применена: в откатываемой транзакции `DETACH PARTITION` → головная проверка краснеет **по значению** («нет партиции на квартал 2026-04-01»), откат возвращает партицию. После теста на проде 12 партиций, 741 874 строки Q2 — цел. - Без БД — 4 теста skip с причиной (allowlist), календарный идёт везде. - `pytest backend/tests/sql` — **55 passed** через туннель к проду. ## Что остаётся вне PR - **Доставка алертов** — сторожа исправны, адресатов нет. Это #2704 (GlitchTip без правил), не новая работа. - **Автосоздание партиций** — сейчас каждый новый квартал = новая миграция. Запас до конца 2026; в начале декабря сторож покраснеет на Q1 2027, и это правильно.
bot-backend added 1 commit 2026-08-21 07:49:14 +00:00
fix(data): партиции rosreestr_deals на Q2–Q4 2026 + загрузчик доходит до файла (#2998)
Some checks failed
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m55s
CI / backend-tests (pull_request) Failing after 17m20s
e6e5bd962c
Задача формулировала «импорт каждый день рапортует done с total_seen=0».
Проверка на проде показала другое: импорт исправен — ежедневно вычитывает
все 96 974 строки FDW-источника и честно их пропускает (rows_fetched =
rows_skipped = 96974), а `total_seen` — поле админ-витрины, не счётчик
импорта. Источник gendesign.rosreestr_deals стоял на Q1 2026 (загружен
30.04), хотя Q2 2026 опубликован Росреестром 10.07 и poll заметил его
14.08 (available=1). Оба сторожа — poll и deals_freshness_monitor —
сработали и семь событий ушли в GlitchTip, где 0 правил / 0 адресатов /
0 отправок.

Корень, которого в задаче не было: rosreestr_deals партиционирована по
period_start_date, партиции созданы списком в 01_schema «2024 Q3 — 2026
Q1», и ничто новые не создаёт. Загрузка Q2 21.08 упала:

  ERROR: no partition of relation "rosreestr_deals" found for row
  DETAIL: (period_start_date) = (2026-04-01)

То есть даже оператор, запустив загрузчик по подсказке poll, получил бы
отказ. Это и объясняет, почему poll сделан «только сообщить».

Что сделано:
• миграция 193 — партиции Q2, Q3, Q4 2026 с запасом, идемпотентно, с
  lock_timeout; индексы наследуются от родителя (проверено: 4 на 2026q2);
• JOBS загрузчика — 2026Q2–Q4 (квартал без CSV честно SKIP);
• ловушка set -e в загрузчике: resolve_csv сигналит «файла нет» кодом 1,
  и первый же квартал без CSV молча ронял ВЕСЬ прогон до строки SKIP — на
  проде с одним Q2-файлом скрипт завершался rc=0, не напечатав ни строки.
  `|| true` на вызове; после правки боевой прогон на VPS: 12 кварталов,
  2026Q2 «уже загружен (741874 строк)», остальные SKIP, rc=0;
• тест-сторож горизонта: партиция обязана существовать на последний
  публикуемый квартал (+20 дней лага после конца квартала; Q2 2026 вышел
  10.07) и на следующий — чтобы предупреждение приходило за квартал до
  отказа, а не в день публикации. Читает pg_inherits живого Postgres.
  Красная сторона воспроизводима на проде, где миграция уже применена:
  DETACH партиции в откатываемой транзакции → головная краснеет по
  значению («нет партиции на квартал 2026-04-01»), откат возвращает
  партицию (проверено: 12 партиций после теста). Без БД — skip с
  причиной, в allowlist; календарный тест идёт везде.

Сам Q2 загружен на прод по штатному пути: 741 874 строки в
rosreestr_deals (ЕКБ-фильтр 13 654), import-rosreestr.sh → tradein.deals
+11 649 сделок, max(deal_date) 2026-01-01 → 2026-04-01.
deals_freshness_monitor на следующем тике: alert 0, latest_quarter 2.

pytest backend/tests/sql — 55 passed (через туннель к проду).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Light1YT added 1 commit 2026-08-21 08:04:39 +00:00
ci: перезапуск backend-tests — джоб завис с 07:49 без обновлений (#2998)
Some checks failed
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m6s
CI / backend-tests (pull_request) Failing after 17m16s
ebb7b7d32d
Остальные семь чеков прошли за минуты, backend-tests стоял 1ч30м без
единого обновления статуса. Actions API на этом Forgejo недоступен
(/actions/tasks обрывает соединение), перезапуск — только новым
коммитом. Код не меняется.
Light1YT added 1 commit 2026-08-21 08:34:01 +00:00
test(#2998): сторож партиций — герметично в схеме-песочнице, а не по живому проду
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
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 / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m59s
CI / backend-tests (pull_request) Successful in 17m6s
9b54d64bd8
(см. описание в PR #3014)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bot-backend merged commit ce466c6d03 into main 2026-08-21 08:56:25 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#3014
No description provided.