A physical building with both Avito ext_house_id (3 listings) and
cian/yandex listings (5 lots, no ext_id) was getting TWO houses rows
(one avito, one derived). Step 4 then split the 8 listings across them.
Fix:
- Step 2 (derived insert): NOT IN (avito-addresses) — skip if already covered
- Step 4 (fuzzy link): COALESCE prefers avito-house at same addr over derived
Adds sanity check: WARN if any normalized address has multiple houses rows.
Backfill 18,428 listings against an empty houses table:
- INSERT Avito/CIAN-sourced houses (~562 unique via house_source+house_ext_id)
- INSERT derived houses for remaining listings (group by tradein_normalize_short_addr,
synthetic ext_house_id = sha256 truncated to 32 hex chars) → ~6102 derived
- UPDATE listings.house_id_fk by both paths (direct: 2997, fuzzy: 15200)
- Best-effort relink orphan house_placement_history via raw_payload.address (0 rows)
Syntax-validated live: 6664 houses, 18197/18428 listings linked (98.8%).
Idempotent (ON CONFLICT DO NOTHING, WHERE house_id_fk IS NULL).
Logs result counters via RAISE NOTICE.
Phase C (Avito IMV history scrape per house) deferred to separate Celery job.