fix(sql): EMISS PK includes period_type so yearly+Q1 coexist (#1606 follow-up) #1706

Merged
lekss361 merged 2 commits from fix/emiss-pk-granularity-1687 into main 2026-06-17 18:46:01 +00:00
Showing only changes of commit 2659600374 - Show all commits

View file

@ -13,9 +13,11 @@
-- 1. Добавляет колонку period_type TEXT NOT NULL DEFAULT 'unknown'.
-- Все существующие строки (CBR, rosstat open-data, domrf) получают 'unknown' —
-- это корректно: у них нет sub-period granularity (они уже различаются по obs_date).
-- 2. Бэкфилл: строки source='emiss' обновляем до 'quarterly' (единственный
-- 2. Бэкфилл: строки source='emiss' обновляем до 'quarter' (единственный
-- активный ЕМИСС-индикатор — income_per_capita, он квартальный; годовых EMISS-
-- строк ещё нет в таблице до этой миграции).
-- строк ещё нет в таблице до этой миграции). Значение ДОЛЖНО совпадать с тем,
-- что пишет UPSERT_EMISS_SQL (_emiss_period_granularity → 'quarter'/'year'/'month',
-- короткая форма), иначе ON CONFLICT не сматчит → дубли при следующем скрейпе.
-- 3. Пересоздаёт PRIMARY KEY: старый (indicator_type, region, obs_date) → новый
-- (indicator_type, region, obs_date, period_type).
-- 4. Пересоздаёт сопутствующий индекс idx_macro_type_region_date с тем же составом
@ -38,11 +40,15 @@ BEGIN;
ALTER TABLE macro_indicator
ADD COLUMN IF NOT EXISTS period_type TEXT NOT NULL DEFAULT 'unknown';
-- ── 2. Бэкфилл ЕМИСС-строк → 'quarterly' ────────────────────────────────────────────
-- Все существующие ЕМИСС-строки — quarterly (income_per_capita). Если появятся 'year'-
-- строки (будущие индикаторы) — они придут с корректным period_type из нового скрейпера.
-- ── 2. Бэкфилл ЕМИСС-строк → 'quarter' ────────────────────────────────────────────
-- Все существующие ЕМИСС-строки — квартальные (income_per_capita). Значение 'quarter'
-- (короткая форма) обязано совпадать с UPSERT_EMISS_SQL, который параметризует
-- period_type из _emiss_period_granularity ('quarter'/'year'/'month'). Иначе после
-- деплоя следующий скрейп вставит 'quarter'-строки, не матчащие 'quarterly' на
-- ON CONFLICT → дубли для каждого квартального наблюдения. Если появятся 'year'-строки
-- (будущие индикаторы) — придут с корректным period_type из скрейпера.
UPDATE macro_indicator
SET period_type = 'quarterly'
SET period_type = 'quarter'
WHERE source = 'emiss'
AND period_type = 'unknown';
@ -60,16 +66,16 @@ EXCEPTION
END;
$$;
-- Новый PK включает period_type. Если уже существует с правильным составом
-- ADD CONSTRAINT бросит duplicate_table (конвенция Pg: PK → unique index), ловим.
-- Новый PK включает period_type. Если constraint с этим именем уже существует —
-- ADD CONSTRAINT бросит duplicate_object (42710, дубль имени constraint), ловим.
DO $$
BEGIN
ALTER TABLE macro_indicator
ADD CONSTRAINT macro_indicator_pkey
PRIMARY KEY (indicator_type, region, obs_date, period_type);
EXCEPTION
WHEN duplicate_table THEN
NULL; -- PK уже создан (повторный прогон)
WHEN duplicate_object THEN
NULL; -- constraint с таким именем уже создан (повторный прогон)
WHEN invalid_table_definition THEN
NULL; -- уже существует тот же constraint
END;