fix(tradein/geocode): бэкфилл listings.city из слага города в URL Авито (#2594) #2606
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2606
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-backfill-listing-city-from-url"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
listings.city(колонка добавлена в 196) для уже накопленных Avito-объявлений из слага города вsource_url(первый сегмент пути,avito.ru/<slug>/...).WHERE source='avito' AND city IS NULL— идемпотентно, не перетирает то, что уже проставил скрапер (go-forward write-path 196).CITY_DISPLAY_NAMES/CITY_LOCATIONSвscraper_kit.orchestration.pipeline.geocode_missing_listings(2026-08-01 13:18 UTC) заберёт в очередь 148 активных объявлений Нижнего Тагила безcity— без города такие адреса ("Хохрякова", "Калинина" — тёзки центральных ЕКБ-улиц) рискуют получить координаты Екатеринбурга. Этот бэкфилл проставляет им city до начала прогона.Замеры (прод, read-only, до написания миграции)
1. Avito,
city IS NULL, по слагу (наши 6 городов):ekaterinburgnizhniy_tagilkamensk-uralskiypervouralskverhnyaya_pyshmaserov2. В очереди сегодняшнего геокодирования (
lat IS NULL AND is_active AND address IS NOT NULL AND length(trim(address))>=5 AND (geocode_tried_at IS NULL OR < now()-7d)), из строк, которые эта миграция снабдит городом:ekaterinburgnizhniy_tagil148 = ровно число из issue — подтверждает диагноз. Остальные 4 города — 0 в очереди сейчас (либо уже геокодированы, либо неактивны), но
cityдля них всё равно бэкфиллится для корректности/будущих геокодов.3. Слаги вне scope: 1650 distinct слагов на Avito всего, 1644 вне наших 6 городов, покрывают 16930 строк с
city IS NULL, которые остаются NULL — отдельное решение владельца (см.Вне scopeниже).4. После написания миграции — SELECT-версия UPDATE с идентичным WHERE:
27706— совпадает с п.1 день-в-день (проверено).Слаг Верхней Пышмы
Проверил фактические значения source_url на проде: встретился ТОЛЬКО вариант
verhnyaya_pyshma(безk, avito_slug изCityLocationв pipeline.py). Второй вариант (verkhnyaya_pyshma— наш внутреннийcity_slug-ключ) в данных не встретился ни разу, поэтому в WHERE/CASE его не добавлял (дал бы 0 доп. строк, а лишняя ветка — риск будущей путаницы).Аналогично для Каменска-Уральского: avito-слаг —
kamensk-uralskiy(ЧЕРЕЗ ДЕФИС), а неkamensk_uralskiy(подчёркивание) как в примере из issue — сверено сCityLocation("kamensk-uralskiy", ...)в pipeline.py и с фактическими данными.Вне scope (сознательно не трогаю)
ekb.cian.ruотдаёт областные объявления, включая тагильские, через тот же хост с параметром региона); бэкфилл по хосту дал бы неверный результат.ekaterinburg.domclick.ru, 13 на голомdomclick.ru; выгоды нет (нет объявлений без координат), 13 неопределённых строк — отдельный разбор.realty.yandex.ru/offer/<id>) города нет вовсе.region_code— у 16912 чужих-региона строк он неверный (66) — отдельный пункт issue #2604, ждёт решения владельца.Test plan
tests/test_migration_197_backfill_listings_city_from_url.py— новый, по образцу 165/191 (transactional, idempotent scope, no DDL, no psycopg trap, слаги/названия сверены с pipeline.py CITY_DISPLAY_NAMES).tests/test_migrations_manifest.py— префикс 197 свободен, не коллизирует.uv run pytest -q --deselect tests/test_search_api.py::test_search_cache_hit(tradein-mvp/backend): 2948 passed, 9 skipped, 1 deselected — только известный pre-existing deselect, без новых красных.Refs #2594