fix(scrapers): COALESCE-backfill listing_date/area_m2 in save_listings ON CONFLICT (Refs #821) #829
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#829
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/821-coalesce-backfill"
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?
Что
save_listings(base.py) наINSERT ... ON CONFLICT (dedup_hash) DO UPDATEНЕ перечислялlisting_dateиarea_m2в SET-блоке → на re-scrape (UPDATE-ветка, ~99% строк) эти поля никогда не backfill'ились. Прод: avitolisting_datecoverage 2.3% и не рос.Как (точный контракт #821)
В SET-блок (после
metro_stations = EXCLUDED.metro_stations) добавлены ровно 2 строки:COALESCE(EXCLUDED.x, listings.x)— свежий non-NULL побеждает, parse-miss (NULL) НЕ затирает уже известное. Больше в SET ничего не менялось, INSERT VALUES не тронут.Тесты
test_base_save_listings.py+3 (SQL-text содержит обе COALESCE; params pass-through; None-params на conflict-path не затирают).pytest -k "save_listings or conflict or persist or backfill"→ 21 passed (mock-DB, in-process). ruff clean.QA после deploy+re-scrape
SELECT count(listing_date)*100.0/count(*) FROM listings WHERE source='avito'— coverage UPDATE-строк должен расти. Комплементарно #726 (parser-input, needs-human) / #775 / #814.Refs #821
✅ APPROVE — точный по контракту #821 фикс persist-half (UPDATE-ветка backfill).
Проверено:
ON CONFLICT (dedup_hash) DO UPDATE SETпослеmetro_stations(запятая добавлена):listing_date = COALESCE(EXCLUDED.listing_date, listings.listing_date),area_m2 = COALESCE(EXCLUDED.area_m2, listings.area_m2). Больше в SET ничего, INSERT VALUES не тронут.EXCLUDED.x(новый скрейп) первым → свежий non-NULL побеждает;listings.x(текущее в БД) → parse-miss (NULL) НЕ затирает уже известное. Решает прод-факт avitolisting_date2.3% не растёт (UPDATE-строки не backfill'ились).Anti-regression: hot-path
save_listings, но изменение только в UPDATE-ветке — INSERT не тронут. Нет конфликта с уже-смерженным #811 (тот добавилgeo_precisionтолько в INSERT, не в SET). Парсеры (#726/#775), estimator, street_sales не тронуты (out-of-scope соблюдён). Секретов/инъекции нет (column-refs).Мержу. #821 → qa. Post-deploy QA:
count(listing_date)*100/count(*) WHERE source='avito'— coverage UPDATE-строк должен расти после re-scrape.