From 521d35fe495328c94c3bb693c6e608cd95368884 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 6 Aug 2026 05:57:00 +0500 Subject: [PATCH] =?UTF-8?q?fix(tradein):=20=D0=B2=D0=B5=D1=80=D0=BD=D1=83?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=BE=D1=82=D0=BE=D0=B3=D1=80=D0=B0=D1=84?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA=D0=B0=D0=B7=D0=BE?= =?UTF-8?q?=D0=BA=20Avito=20IMV=20=D0=B7=D0=B0=D0=B4=D0=BD=D0=B8=D0=BC=20?= =?UTF-8?q?=D1=87=D0=B8=D1=81=D0=BB=D0=BE=D0=BC=20(#2674)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Класс «площадка прислала, парсер разобрал, до базы не доехало». Правка #2682 починила ПУТЬ (парсер отдаёт imageLink, INSERT его перечисляет), но только для будущих строк — исторические так и остались с NULL. Прод 2026-08-06, точные count(*): house_suggestions 25 055 строк, image_link заполнен у 0 house_imv_evaluations 2 685 строк, raw_response есть у 2 685, suggestions.items[0].imageLink есть у 2 685 Сырьё сохранено целиком, поэтому исторические ВОССТАНОВИМЫ: ключ подсказки (house_id, ext_item_id) однозначно ложится на (e.house_id, item->>'id'). SELECT-прогон того же JOIN на проде: 21 480 из 25 055 (85.7%) восстановимо. Остальные 3 575 невосстановимы в принципе, и это не недоделанный бэкфилл: house_imv_evaluations имеет UNIQUE(house_id) и ON CONFLICT DO UPDATE, поэтому повторная оценка дома перетирает raw_response — старый набор подсказок остаётся без своего сырья. Пишу это в комментарий к колонке, чтобы следующий читатель не искал баг в разнице 25 055 vs 21 480. Идемпотентно: WHERE image_link IS NULL — повтор не трогает заполненное и не перетирает то, что напишет живой скрейпер. --- ..._backfill_house_suggestions_image_link.sql | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tradein-mvp/backend/data/sql/221_backfill_house_suggestions_image_link.sql diff --git a/tradein-mvp/backend/data/sql/221_backfill_house_suggestions_image_link.sql b/tradein-mvp/backend/data/sql/221_backfill_house_suggestions_image_link.sql new file mode 100644 index 00000000..698b7114 --- /dev/null +++ b/tradein-mvp/backend/data/sql/221_backfill_house_suggestions_image_link.sql @@ -0,0 +1,44 @@ +-- 221_backfill_house_suggestions_image_link.sql +-- Purpose (#2674, класс «площадка прислала, парсер разобрал, до базы не доехало»): +-- вернуть фотографии подсказок Avito IMV задним числом. +-- +-- Контекст. Колонка house_suggestions.image_link существует с миграции 064; до +-- PR #2682 (2026-08-06) парсер выбрасывал suggestions.items[].imageLink, а INSERT +-- её не перечислял. Правка #2682 чинит только БУДУЩИЕ строки. На проде на момент +-- этой миграции: 25 055 строк house_suggestions, image_link заполнен у 0 (count +-- точный, не reltuples). +-- +-- Почему исторические ВОССТАНОВИМЫ. Полный ответ /web/1/realty-imv/get-data +-- сохраняется целиком в house_imv_evaluations.raw_response (jsonb) — 2 685 строк, +-- у ВСЕХ 2 685 присутствует suggestions.items[0].imageLink. Ключ подсказки +-- (house_id, ext_item_id) однозначно соответствует (e.house_id, item->>'id'). +-- +-- Прод-замер ДО (SELECT-прогон этого же JOIN, 2026-08-06): +-- всего 25 055 · восстановимо 21 480 (85.7%) · не восстановимо 3 575 (14.3%). +-- 3 575 — это подсказки, чей house_id переоценивался позже: house_imv_evaluations +-- имеет UNIQUE(house_id) и ON CONFLICT DO UPDATE перетирает raw_response свежим +-- ответом, поэтому старый набор подсказок остаётся без своего сырья. Эти строки +-- невосстановимы в принципе — не «недоделанный бэкфилл», а утраченный источник. +-- +-- Идемпотентно: WHERE hs.image_link IS NULL — повторный прогон не трогает уже +-- заполненные строки и не перетирает то, что напишет живой скрейпер. +-- +-- Apply after: 216_dead_code_sweep.sql + +BEGIN; + +UPDATE house_suggestions hs +SET image_link = j.item ->> 'imageLink' +FROM house_imv_evaluations e +CROSS JOIN LATERAL jsonb_array_elements(e.raw_response -> 'suggestions' -> 'items') AS j(item) +WHERE e.house_id = hs.house_id + AND j.item ->> 'id' = hs.ext_item_id + AND hs.image_link IS NULL + AND nullif(j.item ->> 'imageLink', '') IS NOT NULL; + +COMMENT ON COLUMN house_suggestions.image_link IS + 'Ссылка на фото лота (suggestions.items[].imageLink). Пишется скрейпером с #2682; ' + 'исторические строки восстановлены из house_imv_evaluations.raw_response миграцией 221 ' + '(21 480 из 25 055; остальные потеряли сырьё при перезаписи оценки дома).'; + +COMMIT; -- 2.45.3