chore(tradein): DROP listings_snapshots.position_in_serp (шаг 2 из 2, #2674) #2697

Closed
opened 2026-08-06 05:50:21 +00:00 by bot-backend · 0 comments
Collaborator

Продолжение PR #2694. Там код перестал упоминать колонку и миграция 217 подписала её COMMENT'ом с диагнозом; здесь — сам DROP.

Что нужно

ALTER TABLE listings_snapshots DROP COLUMN IF EXISTS position_in_serp;

Один файл data/sql/NNN_drop_position_in_serp.sql со ссылкой на 217 и на #2674.

Почему отдельным PR, а не вместе с кодом

deploy-tradein.yml применяет data/sql/*.sql до перезапуска контейнеров («(3) Применяем SQL миграции — ДО app»). DROP в одном деплое с правкой писателя оставил бы окно в несколько минут, где ещё живой СТАРЫЙ образ выполняет INSERT со списком колонок, включающим удалённую. Запись снэпшотов fault-tolerant (SAVEPOINT + logger.warning), поэтому упало бы ТИХО — потерянные за это окно снэпшоты цен заметили бы через недели по дырке в истории.

Предусловие (проверить перед мержем)

Образ с PR #2694 должен уже жить на проде. Проверка по коду в контейнере, не по факту «деплой зелёный»:

ssh gendesign "docker exec tradein-scraper python -c \"
import scraper_kit.snapshot_writer as m, inspect
print('position_in_serp' in inspect.getsource(m))  # ожидается только в docstring, не в SQL
print('position_in_serp' in inspect.signature(m.upsert_listing_snapshot).parameters)  # False
\""

Почему колонка удаляется, а не подключается

Кратко (полный разбор — в 217_position_in_serp_unexpressible.sql): позиция есть свойство пары (объявление, конкретный прогон выдачи с конкретными фильтрами), а PRIMARY KEY (listing_id, snapshot_date) держит одну строку на объявление в сутки. За 2026-08-03 по этому ключу писали 13 разных run_id и четыре SERP-источника; внутри одного city_sweep объявление приезжает с разным индексом от перекрывающихся гео-якорей. Значение осело бы от последнего писателя дня и читалось бы как факт.

Читателей нет: колонка пуста 0/395240, 0 view/matview на проде ссылаются на неё.

Если позиция когда-нибудь понадобится — это НЕ возврат колонки, а новая таблица с ключом (run_id, listing_id) и сохранёнными фильтрами прогона.

Refs #2674

Продолжение PR #2694. Там код перестал упоминать колонку и миграция 217 подписала её COMMENT'ом с диагнозом; здесь — сам DROP. ## Что нужно ```sql ALTER TABLE listings_snapshots DROP COLUMN IF EXISTS position_in_serp; ``` Один файл `data/sql/NNN_drop_position_in_serp.sql` со ссылкой на 217 и на #2674. ## Почему отдельным PR, а не вместе с кодом `deploy-tradein.yml` применяет `data/sql/*.sql` **до** перезапуска контейнеров («(3) Применяем SQL миграции — ДО app»). DROP в одном деплое с правкой писателя оставил бы окно в несколько минут, где ещё живой СТАРЫЙ образ выполняет `INSERT` со списком колонок, включающим удалённую. Запись снэпшотов fault-tolerant (SAVEPOINT + `logger.warning`), поэтому упало бы ТИХО — потерянные за это окно снэпшоты цен заметили бы через недели по дырке в истории. ## Предусловие (проверить перед мержем) Образ с PR #2694 должен уже жить на проде. Проверка по коду в контейнере, не по факту «деплой зелёный»: ```bash ssh gendesign "docker exec tradein-scraper python -c \" import scraper_kit.snapshot_writer as m, inspect print('position_in_serp' in inspect.getsource(m)) # ожидается только в docstring, не в SQL print('position_in_serp' in inspect.signature(m.upsert_listing_snapshot).parameters) # False \"" ``` ## Почему колонка удаляется, а не подключается Кратко (полный разбор — в 217_position_in_serp_unexpressible.sql): позиция есть свойство пары (объявление, конкретный прогон выдачи с конкретными фильтрами), а `PRIMARY KEY (listing_id, snapshot_date)` держит одну строку на объявление в сутки. За 2026-08-03 по этому ключу писали 13 разных `run_id` и четыре SERP-источника; внутри одного `city_sweep` объявление приезжает с разным индексом от перекрывающихся гео-якорей. Значение осело бы от последнего писателя дня и читалось бы как факт. Читателей нет: колонка пуста 0/395240, 0 view/matview на проде ссылаются на неё. Если позиция когда-нибудь понадобится — это НЕ возврат колонки, а новая таблица с ключом `(run_id, listing_id)` и сохранёнными фильтрами прогона. Refs #2674
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#2697
No description provided.