gendesign/_wt-cadval/data/sql/154_ekb_district_demographics.sql
bot-backend 542ff1c9ca docs(tradein/domclick): два комментария описывали пул, которого нет с миграции 253
Оба места утверждали, что у Домклика один выделенный резидентный прокси и
пула нет. Это перестало быть правдой ещё в #2800 (миграция 253 сняла
резервацию узла), но текст остался — и именно на него опирался тикет #3189,
поставленный под «калибровку» ограничения, которого не существует.
Свип к тому же ходит через пул давно (serp.py:359), а бэкфилл подключён к
нему в PR #3222.

Заодно докстринг называл не тот ограничитель: свип кладёт не счётчик
провалов lease, а break по первому DomClickBlockedError (#2854) — до
ротации дело не доходит ни при каком счётчике, отсюда buckets_completed=0.

Только комментарии, поведение не меняется. Миграция 175 уже применена, а
_schema_migrations трекает по имени файла без checksum — правка текста
её не перезапустит.
2026-08-29 18:57:25 +03:00

107 lines
7.8 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Контекст: Issue #42 (Infra I1) — POI saturation per capita. Чтобы считать
-- обеспеченность инфраструктурой района (школа/детсад/поликлиника на
-- 1000 чел. целевой когорты vs норматив СП 42.13330), нужна демография
-- по 8 внутригородским районам ЕКБ.
--
-- Что делает:
-- 1. Заполняет ekb_districts.population (была NULL) точными числами Росстата.
-- 2. Создаёт таблицу-справочник ekb_district_demographics — насел./площадь/ОКАТО
-- + ДОКУМЕНТИРОВАННЫЙ источник/дата + ОЦЕНОЧНЫЕ возрастные когорты (помечены).
--
-- ИСТОЧНИК населения (источник истины):
-- Wikipedia «Административно-территориальное деление Екатеринбурга» →
-- первоисточник «Численность постоянного населения РФ по муниципальным
-- образованиям на 1 января 2025», Росстат. as_of_date = 2025-01-01.
--
-- ВОЗРАСТНЫЕ КОГОРТЫ — ОЦЕНКА, НЕ ФАКТ. На уровне внутригородского района Росстат
-- публичных половозрастных срезов НЕ даёт. Применены РЕГИОНАЛЬНЫЕ доли (РФ/Свердл.
-- обл., перепись-2020 / EMISS, порядок величин):
-- • дошкольники 0-7 ≈ 8.0 % (age_share_preschool)
-- • школьники 7-18 ≈ 11.5 % (age_share_school)
-- • пожилые 65+ ≈ 16.0 % (age_share_elderly)
-- Это ГРУБАЯ оценка для saturation-расчёта (estimate-флаг в API). Реальные
-- район-уровневые доли потребуют отдельного источника (см. issue #42 risks).
--
-- Deploy order: после 56_schema_ekb_districts_geom (FK на ekb_districts) — стоит.
-- Idempotent: CREATE TABLE IF NOT EXISTS + INSERT … ON CONFLICT DO UPDATE
-- (re-apply перезаписывает данными из этой миграции — single source).
-- Deploy: auto-applied by deploy.yml через _schema_migrations tracking (ровно один раз по NN).
BEGIN;
-- ── 1. Справочник демографии района ──────────────────────────────────────────
CREATE TABLE IF NOT EXISTS ekb_district_demographics (
district_name TEXT PRIMARY KEY
REFERENCES ekb_districts(district_name),
population INTEGER NOT NULL, -- чел., Росстат 2025-01-01
area_km2 NUMERIC(8, 2) NOT NULL, -- км²
okato TEXT, -- код ОКАТО района
-- Возрастные доли — ОЦЕНКА (региональный fallback), а не район-факт.
age_share_preschool NUMERIC(5, 4), -- доля 0-7 лет (детсад)
age_share_school NUMERIC(5, 4), -- доля 7-18 лет (школа)
age_share_elderly NUMERIC(5, 4), -- доля 65+ лет (поликлиника)
age_cohorts_estimated BOOLEAN NOT NULL DEFAULT TRUE, -- TRUE = когорты оценочные
source TEXT NOT NULL, -- человекочитаемый источник
as_of_date DATE NOT NULL, -- дата актуальности населения
loaded_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
COMMENT ON TABLE ekb_district_demographics IS
'Демография 8 внутригородских районов ЕКБ для POI saturation per capita (#42). '
'population/area — Росстат 2025-01-01 (факт). Возрастные когорты — ОЦЕНКА '
'(региональные доли РФ/Свердл.), см. age_cohorts_estimated.';
COMMENT ON COLUMN ekb_district_demographics.age_cohorts_estimated IS
'TRUE: age_share_* — оценка региональными долями, НЕ район-факт Росстата (#42).';
-- ── 2. Seed: 8 районов (Росстат на 1 января 2025) ────────────────────────────
-- population/area/okato — ФАКТ. age_share_* — единая региональная оценка (см. шапку).
INSERT INTO ekb_district_demographics
(district_name, population, area_km2, okato,
age_share_preschool, age_share_school, age_share_elderly,
age_cohorts_estimated, source, as_of_date)
VALUES
('Академический', 125000, 46.01, '65401362', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Верх-Исетский', 240822, 219.79, '65401364', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Железнодорожный', 158675, 125.65, '65401368', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Кировский', 220749, 86.25, '65401373', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Ленинский', 222258, 22.19, '65401377', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Октябрьский', 151775, 158.60, '65401380', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Орджоникидзевский', 263820, 99.30, '65401385', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01'),
('Чкаловский', 286277, 389.81, '65401390', 0.0800, 0.1150, 0.1600, TRUE,
'Росстат, численность населения МО на 01.01.2025 (via Wikipedia АТД Екатеринбурга)',
DATE '2025-01-01')
ON CONFLICT (district_name) DO UPDATE SET
population = EXCLUDED.population,
area_km2 = EXCLUDED.area_km2,
okato = EXCLUDED.okato,
age_share_preschool = EXCLUDED.age_share_preschool,
age_share_school = EXCLUDED.age_share_school,
age_share_elderly = EXCLUDED.age_share_elderly,
age_cohorts_estimated = EXCLUDED.age_cohorts_estimated,
source = EXCLUDED.source,
as_of_date = EXCLUDED.as_of_date,
loaded_at = now();
-- ── 3. Backfill ekb_districts.population (была NULL) — по name-match ──────────
-- ekb_districts.area_m2 уже есть в схеме (NUMERIC) — конвертируем км² → м².
UPDATE ekb_districts d
SET population = s.population,
area_m2 = COALESCE(d.area_m2, s.area_km2 * 1000000.0)
FROM ekb_district_demographics s
WHERE d.district_name = s.district_name;
COMMIT;