Merge pull request 'fix(tradein): hotfix миграции 108 — deploy red (typo + collision-safe репойнт)' (#1547) from fix/migration-108-collision-safe into main
Some checks failed
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Failing after 35s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
Some checks failed
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Failing after 35s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
Reviewed-on: #1547
This commit is contained in:
commit
7d39aebbd4
1 changed files with 57 additions and 33 deletions
|
|
@ -23,7 +23,7 @@
|
||||||
-- house_imv_evaluations (house_id) — CASCADE — UNIQUE(house_id) → dedup
|
-- house_imv_evaluations (house_id) — CASCADE — UNIQUE(house_id) → dedup
|
||||||
-- house_suggestions (house_id) — CASCADE — UNIQUE(house_id, ext_item_id) → dedup
|
-- house_suggestions (house_id) — CASCADE — UNIQUE(house_id, ext_item_id) → dedup
|
||||||
-- external_valuations (house_id) — CASCADE — нет ограничивающего UNIQUE
|
-- external_valuations (house_id) — CASCADE — нет ограничивающего UNIQUE
|
||||||
-- address_mismatch_audit (house_id) — CASCADE — нет ограничивающего UNIQUE
|
-- address_mismatch_audit (house_id) — CASCADE — UNIQUE(house_id,audit_batch) → dedup
|
||||||
--
|
--
|
||||||
-- Идемпотентность: все UPDATE/DELETE ищут по mapping временной таблицы. При повторном
|
-- Идемпотентность: все UPDATE/DELETE ищут по mapping временной таблицы. При повторном
|
||||||
-- запуске mapping будет пустым (дублей нет) → все UPDATE/DELETE затронут 0 строк → no-op.
|
-- запуске mapping будет пустым (дублей нет) → все UPDATE/DELETE затронут 0 строк → no-op.
|
||||||
|
|
@ -80,7 +80,7 @@ clusters_with_count AS (
|
||||||
),
|
),
|
||||||
-- Только дома, входящие в кластер-дубль
|
-- Только дома, входящие в кластер-дубль
|
||||||
dup_houses AS (
|
dup_houses AS (
|
||||||
SELECT h.id, c.cluster_key
|
SELECT h.id, cl.cluster_key
|
||||||
FROM houses h
|
FROM houses h
|
||||||
JOIN clustered cl ON cl.id = h.id
|
JOIN clustered cl ON cl.id = h.id
|
||||||
JOIN clusters_with_count cw ON cw.cluster_key = cl.cluster_key
|
JOIN clusters_with_count cw ON cw.cluster_key = cl.cluster_key
|
||||||
|
|
@ -203,47 +203,58 @@ FROM _108_dup_mapping m
|
||||||
WHERE haa.house_id = m.dup_id;
|
WHERE haa.house_id = m.dup_id;
|
||||||
|
|
||||||
-- 3c. houses_price_dynamics UNIQUE(house_id, month_date, source)
|
-- 3c. houses_price_dynamics UNIQUE(house_id, month_date, source)
|
||||||
-- Удалить строки дубля, у которых (month_date,source) уже есть у canonical.
|
-- Collision-safe: дедуп по ЦЕЛЕВОМУ ключу (canonical, month_date, source) —
|
||||||
DELETE FROM houses_price_dynamics hpd
|
-- ловит и dup-vs-canonical, и dup-vs-dup в кластерах >2. Выживает строка
|
||||||
USING _108_dup_mapping m
|
-- canonical'а (m.canonical_id IS NULL), иначе минимальный id.
|
||||||
WHERE hpd.house_id = m.dup_id
|
DELETE FROM houses_price_dynamics t
|
||||||
AND EXISTS (
|
USING (
|
||||||
SELECT 1 FROM houses_price_dynamics hpd2
|
SELECT t2.id,
|
||||||
WHERE hpd2.house_id = m.canonical_id
|
ROW_NUMBER() OVER (
|
||||||
AND hpd2.month_date = hpd.month_date
|
PARTITION BY COALESCE(m.canonical_id, t2.house_id), t2.month_date, t2.source
|
||||||
AND hpd2.source = hpd.source
|
ORDER BY (m.canonical_id IS NULL) DESC, t2.id ASC
|
||||||
);
|
) AS rn
|
||||||
-- Репойнтить оставшиеся
|
FROM houses_price_dynamics t2
|
||||||
|
LEFT JOIN _108_dup_mapping m ON m.dup_id = t2.house_id
|
||||||
|
) d
|
||||||
|
WHERE t.id = d.id AND d.rn > 1;
|
||||||
|
-- Репойнтить оставшиеся (целевой ключ теперь свободен)
|
||||||
UPDATE houses_price_dynamics hpd
|
UPDATE houses_price_dynamics hpd
|
||||||
SET house_id = m.canonical_id
|
SET house_id = m.canonical_id
|
||||||
FROM _108_dup_mapping m
|
FROM _108_dup_mapping m
|
||||||
WHERE hpd.house_id = m.dup_id;
|
WHERE hpd.house_id = m.dup_id;
|
||||||
|
|
||||||
-- 3d. house_imv_evaluations UNIQUE(house_id) — у canonical уже может быть запись
|
-- 3d. house_imv_evaluations UNIQUE(house_id)
|
||||||
-- Удалить строки дубля если canonical уже имеет evaluation.
|
-- Collision-safe: одна evaluation на canonical. Выживает canonical'а, иначе min id.
|
||||||
DELETE FROM house_imv_evaluations hie
|
DELETE FROM house_imv_evaluations t
|
||||||
USING _108_dup_mapping m
|
USING (
|
||||||
WHERE hie.house_id = m.dup_id
|
SELECT t2.id,
|
||||||
AND EXISTS (
|
ROW_NUMBER() OVER (
|
||||||
SELECT 1 FROM house_imv_evaluations hie2
|
PARTITION BY COALESCE(m.canonical_id, t2.house_id)
|
||||||
WHERE hie2.house_id = m.canonical_id
|
ORDER BY (m.canonical_id IS NULL) DESC, t2.id ASC
|
||||||
);
|
) AS rn
|
||||||
-- Репойнтить оставшиеся (canonical не имеет evaluation — забираем от дубля)
|
FROM house_imv_evaluations t2
|
||||||
|
LEFT JOIN _108_dup_mapping m ON m.dup_id = t2.house_id
|
||||||
|
) d
|
||||||
|
WHERE t.id = d.id AND d.rn > 1;
|
||||||
|
-- Репойнтить оставшиеся
|
||||||
UPDATE house_imv_evaluations hie
|
UPDATE house_imv_evaluations hie
|
||||||
SET house_id = m.canonical_id
|
SET house_id = m.canonical_id
|
||||||
FROM _108_dup_mapping m
|
FROM _108_dup_mapping m
|
||||||
WHERE hie.house_id = m.dup_id;
|
WHERE hie.house_id = m.dup_id;
|
||||||
|
|
||||||
-- 3e. house_suggestions UNIQUE(house_id, ext_item_id)
|
-- 3e. house_suggestions UNIQUE(house_id, ext_item_id)
|
||||||
-- Удалить строки дубля, у которых (ext_item_id) уже есть у canonical.
|
-- Collision-safe: дедуп по (canonical, ext_item_id) — ловит dup-vs-dup.
|
||||||
DELETE FROM house_suggestions hs
|
DELETE FROM house_suggestions t
|
||||||
USING _108_dup_mapping m
|
USING (
|
||||||
WHERE hs.house_id = m.dup_id
|
SELECT t2.id,
|
||||||
AND EXISTS (
|
ROW_NUMBER() OVER (
|
||||||
SELECT 1 FROM house_suggestions hs2
|
PARTITION BY COALESCE(m.canonical_id, t2.house_id), t2.ext_item_id
|
||||||
WHERE hs2.house_id = m.canonical_id
|
ORDER BY (m.canonical_id IS NULL) DESC, t2.id ASC
|
||||||
AND hs2.ext_item_id = hs.ext_item_id
|
) AS rn
|
||||||
);
|
FROM house_suggestions t2
|
||||||
|
LEFT JOIN _108_dup_mapping m ON m.dup_id = t2.house_id
|
||||||
|
) d
|
||||||
|
WHERE t.id = d.id AND d.rn > 1;
|
||||||
-- Репойнтить оставшиеся
|
-- Репойнтить оставшиеся
|
||||||
UPDATE house_suggestions hs
|
UPDATE house_suggestions hs
|
||||||
SET house_id = m.canonical_id
|
SET house_id = m.canonical_id
|
||||||
|
|
@ -268,7 +279,20 @@ SET house_id = m.canonical_id
|
||||||
FROM _108_dup_mapping m
|
FROM _108_dup_mapping m
|
||||||
WHERE ev.house_id = m.dup_id;
|
WHERE ev.house_id = m.dup_id;
|
||||||
|
|
||||||
-- 3i. address_mismatch_audit (CASCADE, нет блокирующего UNIQUE)
|
-- 3i. address_mismatch_audit UNIQUE(house_id, audit_batch) — collision-safe
|
||||||
|
-- (заголовок ранее ошибочно помечал «нет блокирующего UNIQUE»).
|
||||||
|
DELETE FROM address_mismatch_audit t
|
||||||
|
USING (
|
||||||
|
SELECT t2.id,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY COALESCE(m.canonical_id, t2.house_id), t2.audit_batch
|
||||||
|
ORDER BY (m.canonical_id IS NULL) DESC, t2.id ASC
|
||||||
|
) AS rn
|
||||||
|
FROM address_mismatch_audit t2
|
||||||
|
LEFT JOIN _108_dup_mapping m ON m.dup_id = t2.house_id
|
||||||
|
) d
|
||||||
|
WHERE t.id = d.id AND d.rn > 1;
|
||||||
|
-- Репойнтить оставшиеся
|
||||||
UPDATE address_mismatch_audit ama
|
UPDATE address_mismatch_audit ama
|
||||||
SET house_id = m.canonical_id
|
SET house_id = m.canonical_id
|
||||||
FROM _108_dup_mapping m
|
FROM _108_dup_mapping m
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue