All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m16s
Три XLSX ЦБ (выдачи, ставка, задолженность) в разрезе субъектов, помесячно с 01.2019, + ключевая ставка через SOAP DailyInfo.asmx (метод KeyRate; GET на нём не работает, только POST). Всё анонимно, без ключа. Таблицы: cbr_mortgage_series (region, period_month, series) и cbr_key_rate. fetched_at НЕ обновляется в DO UPDATE — по уроку #2846 колонка значит «когда мы ВПЕРВЫЕ увидели период» и по ней меряется такт публикации источника. Раскладка листов у ЦБ РАЗНАЯ, и это ловушка: в 02_11/02_13 шапка периодов в строке 3 текстом («Январь 2019»), а в 02_14 (задолженность) — уже в строке 2 и настоящими datetime. С захардкоженным индексом строки серия debt_rub молча давала НОЛЬ строк при зелёных тестах. Теперь строка шапки ищется динамически: берётся строка с наибольшим числом распознанных периодов среди первых шести. Проверено на живых файлах: каждая из трёх серий даёт 8 736 точек (96 территорий × 91 месяц, 01.2019–07.2026); по Свердловской области 91 месяц, последняя ставка 11.49. estimator.py не тронут: как ипотечная ставка войдёт в оценку — отдельное продуктовое решение, этот PR только про данные. Миграции 292 (таблицы) и 293 (сид расписания, enabled=false, interval_days 7). Новая зависимость: openpyxl.
87 lines
5.8 KiB
PL/PgSQL
87 lines
5.8 KiB
PL/PgSQL
-- 292_cbr_macro_series.sql
|
||
-- Макро-ряды ЦБ РФ: ипотека по субъектам + ключевая ставка.
|
||
--
|
||
-- Context:
|
||
-- ЦБ РФ публикует месячную статистику по ипотечным жилищным кредитам (объём выдач,
|
||
-- ставки, задолженность) в разрезе субъектов РФ — три XLSX-дашборда на cbr.ru
|
||
-- (см. app/services/cbr_macro.py::CBR_MORTGAGE_SERIES) — и дневную ключевую ставку
|
||
-- через SOAP-сервис DailyInfoWebServ. Обе серии нужны как макро-контекст для
|
||
-- продукта (региональная динамика ипотечного рынка); загрузку в estimator этот
|
||
-- PR не делает — только данные и их сбор (app/tasks/cbr_macro_pull.py).
|
||
--
|
||
-- Schema notes:
|
||
-- cbr_mortgage_series
|
||
-- * region — территория как в источнике (РФ целиком / федеральный округ /
|
||
-- субъект), без нормализации кодов ОКАТО.
|
||
-- * period_month — первое число отчётного месяца (шапка XLSX «Месяц Год»).
|
||
-- * series — slug серии (rate_rub / new_loans_rub / debt_rub, конфиг —
|
||
-- CBR_MORTGAGE_SERIES в коде).
|
||
-- * PRIMARY KEY (region, period_month, series) — одно значение на территорию×месяц×серию.
|
||
-- * fetched_at — «когда мы ВПЕРВЫЕ увидели этот период» (не время последней
|
||
-- загрузки — источник даёт всю серию целиком, отсечки по
|
||
-- периоду нет). Урок #2846 у sber_price_index: НЕ обновлять
|
||
-- fetched_at в ON CONFLICT DO UPDATE, иначе один прогон
|
||
-- перезаписывает метку у всех периодов, включая 2019-01.
|
||
-- cbr_key_rate
|
||
-- * rate_date — дата действия ключевой ставки (PRIMARY KEY).
|
||
-- * rate — значение ставки, % годовых.
|
||
-- * fetched_at — по той же логике, что и выше: не трогаем в DO UPDATE.
|
||
--
|
||
-- Idempotent: CREATE TABLE IF NOT EXISTS — безопасно переприменять. Только ADDITIVE.
|
||
--
|
||
-- Dependencies: нет (самостоятельные таблицы).
|
||
-- Deploy order: применить до app/services/cbr_macro.py + app/tasks/cbr_macro_pull.py
|
||
-- + миграции 291 (сид scrape_schedules).
|
||
|
||
BEGIN;
|
||
SET LOCAL lock_timeout = '5s';
|
||
|
||
CREATE TABLE IF NOT EXISTS cbr_mortgage_series (
|
||
region text NOT NULL,
|
||
period_month date NOT NULL,
|
||
series text NOT NULL,
|
||
value double precision NOT NULL,
|
||
source text NOT NULL DEFAULT 'cbr',
|
||
fetched_at timestamptz NOT NULL DEFAULT now(),
|
||
PRIMARY KEY (region, period_month, series)
|
||
);
|
||
|
||
COMMENT ON TABLE cbr_mortgage_series IS
|
||
'Месячные ряды ипотечной статистики ЦБ РФ по территориям (РФ / ФО / субъекты): '
|
||
'объём выдач, ставки, задолженность. Источник — XLSX-дашборды cbr.ru/vfs/statistics/'
|
||
'BankSector/Mortgage/. Загружается app/tasks/cbr_macro_pull.py через in-app '
|
||
'планировщик (scrape_schedules.source=''cbr_macro_pull'').';
|
||
|
||
COMMENT ON COLUMN cbr_mortgage_series.region IS
|
||
'Территория как в источнике (например «РОССИЙСКАЯ ФЕДЕРАЦИЯ», «ЦЕНТРАЛЬНЫЙ '
|
||
'ФЕДЕРАЛЬНЫЙ ОКРУГ», «Свердловская область»). Без нормализации ОКАТО/ISO.';
|
||
COMMENT ON COLUMN cbr_mortgage_series.period_month IS
|
||
'Первое число отчётного месяца (нормализовано из шапки «Месяц Год» XLSX).';
|
||
COMMENT ON COLUMN cbr_mortgage_series.series IS
|
||
'Slug серии, см. CBR_MORTGAGE_SERIES в app/services/cbr_macro.py '
|
||
'(rate_rub, new_loans_rub, debt_rub).';
|
||
COMMENT ON COLUMN cbr_mortgage_series.value IS
|
||
'Значение серии в единицах источника (% годовых для ставки, млн руб для объёмов).';
|
||
COMMENT ON COLUMN cbr_mortgage_series.fetched_at IS
|
||
'Когда мы ВПЕРВЫЕ увидели этот период (не время последней загрузки). '
|
||
'НЕ обновляется в ON CONFLICT DO UPDATE — см. урок #2846 у sber_price_index.';
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_cbr_mortgage_series_region_series_period
|
||
ON cbr_mortgage_series (region, series, period_month DESC);
|
||
|
||
CREATE TABLE IF NOT EXISTS cbr_key_rate (
|
||
rate_date date PRIMARY KEY,
|
||
rate double precision NOT NULL,
|
||
fetched_at timestamptz NOT NULL DEFAULT now()
|
||
);
|
||
|
||
COMMENT ON TABLE cbr_key_rate IS
|
||
'Ключевая ставка ЦБ РФ по датам действия. Источник — SOAP-метод KeyRate '
|
||
'сервиса https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx. Загружается '
|
||
'app/tasks/cbr_macro_pull.py.';
|
||
COMMENT ON COLUMN cbr_key_rate.rate_date IS 'Дата, с которой действует значение ставки.';
|
||
COMMENT ON COLUMN cbr_key_rate.rate IS 'Ключевая ставка, % годовых.';
|
||
COMMENT ON COLUMN cbr_key_rate.fetched_at IS
|
||
'Когда мы ВПЕРВЫЕ увидели эту дату. НЕ обновляется в ON CONFLICT DO UPDATE.';
|
||
|
||
COMMIT;
|