5.2.2: Логирование пути и версии миграций
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m21s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m21s
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
-- Migration: Rollback to MV using max_score and restore max_score column.
|
||||
|
||||
DROP MATERIALIZED VIEW IF EXISTS projects_median_mv;
|
||||
ALTER TABLE weekly_goals ADD COLUMN IF NOT EXISTS max_score NUMERIC(10,4);
|
||||
UPDATE weekly_goals SET max_score = max_goal_score WHERE max_score IS NULL;
|
||||
|
||||
DROP MATERIALIZED VIEW IF EXISTS weekly_report_mv;
|
||||
|
||||
CREATE MATERIALIZED VIEW weekly_report_mv AS
|
||||
SELECT
|
||||
p.id AS project_id,
|
||||
agg.report_year,
|
||||
agg.report_week,
|
||||
COALESCE(agg.total_score, 0.0000) AS total_score,
|
||||
CASE
|
||||
WHEN wg.max_score IS NULL THEN COALESCE(agg.total_score, 0.0000)
|
||||
ELSE LEAST(COALESCE(agg.total_score, 0.0000), wg.max_score)
|
||||
END AS normalized_total_score
|
||||
FROM
|
||||
projects p
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
n.project_id,
|
||||
EXTRACT(ISOYEAR FROM n.created_date)::INTEGER AS report_year,
|
||||
EXTRACT(WEEK FROM n.created_date)::INTEGER AS report_week,
|
||||
SUM(n.score) AS total_score
|
||||
FROM
|
||||
nodes n
|
||||
WHERE
|
||||
(EXTRACT(ISOYEAR FROM n.created_date)::INTEGER < EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER)
|
||||
OR (EXTRACT(ISOYEAR FROM n.created_date)::INTEGER = EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER
|
||||
AND EXTRACT(WEEK FROM n.created_date)::INTEGER < EXTRACT(WEEK FROM CURRENT_DATE)::INTEGER)
|
||||
GROUP BY
|
||||
1, 2, 3
|
||||
) agg
|
||||
ON p.id = agg.project_id
|
||||
LEFT JOIN
|
||||
weekly_goals wg
|
||||
ON wg.project_id = p.id
|
||||
AND wg.goal_year = agg.report_year
|
||||
AND wg.goal_week = agg.report_week
|
||||
WHERE
|
||||
p.deleted = FALSE
|
||||
ORDER BY
|
||||
p.id, agg.report_year, agg.report_week
|
||||
WITH DATA;
|
||||
|
||||
CREATE INDEX idx_weekly_report_mv_project_year_week
|
||||
ON weekly_report_mv(project_id, report_year, report_week);
|
||||
|
||||
COMMENT ON MATERIALIZED VIEW weekly_report_mv IS 'Materialized view aggregating weekly scores by project using ISOYEAR for correct week calculations at year boundaries. Includes all projects via LEFT JOIN. Adds normalized_total_score using weekly_goals.max_score snapshot. Contains only historical data (excludes current week). Uses nodes.created_date (denormalized) instead of entries.created_date.';
|
||||
|
||||
-- Recreate projects_median_mv (last 4 weeks per 000008)
|
||||
CREATE MATERIALIZED VIEW projects_median_mv AS
|
||||
SELECT
|
||||
p.id AS project_id,
|
||||
p.user_id,
|
||||
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY normalized_total_score) AS median_score
|
||||
FROM (
|
||||
SELECT
|
||||
project_id,
|
||||
normalized_total_score,
|
||||
report_year,
|
||||
report_week,
|
||||
ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY report_year DESC, report_week DESC) as rn
|
||||
FROM weekly_report_mv
|
||||
WHERE
|
||||
(report_year < EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER)
|
||||
OR (report_year = EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER
|
||||
AND report_week < EXTRACT(WEEK FROM CURRENT_DATE)::INTEGER)
|
||||
) sub
|
||||
JOIN projects p ON p.id = sub.project_id
|
||||
WHERE rn <= 4 AND p.deleted = FALSE
|
||||
GROUP BY p.id, p.user_id
|
||||
WITH DATA;
|
||||
|
||||
CREATE INDEX idx_projects_median_mv_project_id ON projects_median_mv(project_id);
|
||||
CREATE INDEX idx_projects_median_mv_user_id ON projects_median_mv(user_id);
|
||||
|
||||
COMMENT ON MATERIALIZED VIEW projects_median_mv IS 'Materialized view calculating median score for each project based on last 4 weeks of historical data. Includes user_id for multi-tenant support.';
|
||||
@@ -0,0 +1,82 @@
|
||||
-- Migration: Fix weekly_report_mv to use max_goal_score for normalized_total_score.
|
||||
-- Safe to run on DBs where 000020 was not applied (MV still uses max_score, column exists but is NULL).
|
||||
-- projects_median_mv depends on weekly_report_mv, so we drop and recreate it.
|
||||
|
||||
DROP MATERIALIZED VIEW IF EXISTS projects_median_mv;
|
||||
DROP MATERIALIZED VIEW IF EXISTS weekly_report_mv;
|
||||
|
||||
CREATE MATERIALIZED VIEW weekly_report_mv AS
|
||||
SELECT
|
||||
p.id AS project_id,
|
||||
agg.report_year,
|
||||
agg.report_week,
|
||||
COALESCE(agg.total_score, 0.0000) AS total_score,
|
||||
CASE
|
||||
WHEN wg.max_goal_score IS NULL THEN COALESCE(agg.total_score, 0.0000)
|
||||
ELSE LEAST(COALESCE(agg.total_score, 0.0000), wg.max_goal_score)
|
||||
END AS normalized_total_score
|
||||
FROM
|
||||
projects p
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT
|
||||
n.project_id,
|
||||
EXTRACT(ISOYEAR FROM n.created_date)::INTEGER AS report_year,
|
||||
EXTRACT(WEEK FROM n.created_date)::INTEGER AS report_week,
|
||||
SUM(n.score) AS total_score
|
||||
FROM
|
||||
nodes n
|
||||
WHERE
|
||||
(EXTRACT(ISOYEAR FROM n.created_date)::INTEGER < EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER)
|
||||
OR (EXTRACT(ISOYEAR FROM n.created_date)::INTEGER = EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER
|
||||
AND EXTRACT(WEEK FROM n.created_date)::INTEGER < EXTRACT(WEEK FROM CURRENT_DATE)::INTEGER)
|
||||
GROUP BY
|
||||
1, 2, 3
|
||||
) agg
|
||||
ON p.id = agg.project_id
|
||||
LEFT JOIN
|
||||
weekly_goals wg
|
||||
ON wg.project_id = p.id
|
||||
AND wg.goal_year = agg.report_year
|
||||
AND wg.goal_week = agg.report_week
|
||||
WHERE
|
||||
p.deleted = FALSE
|
||||
ORDER BY
|
||||
p.id, agg.report_year, agg.report_week
|
||||
WITH DATA;
|
||||
|
||||
CREATE INDEX idx_weekly_report_mv_project_year_week
|
||||
ON weekly_report_mv(project_id, report_year, report_week);
|
||||
|
||||
COMMENT ON MATERIALIZED VIEW weekly_report_mv IS 'Materialized view aggregating weekly scores by project using ISOYEAR for correct week calculations at year boundaries. Includes all projects via LEFT JOIN. Adds normalized_total_score using weekly_goals.max_goal_score. Contains only historical data (excludes current week). Uses nodes.created_date (denormalized) instead of entries.created_date.';
|
||||
|
||||
-- Recreate projects_median_mv (depends on weekly_report_mv, last 4 weeks per 000008)
|
||||
CREATE MATERIALIZED VIEW projects_median_mv AS
|
||||
SELECT
|
||||
p.id AS project_id,
|
||||
p.user_id,
|
||||
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY normalized_total_score) AS median_score
|
||||
FROM (
|
||||
SELECT
|
||||
project_id,
|
||||
normalized_total_score,
|
||||
report_year,
|
||||
report_week,
|
||||
ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY report_year DESC, report_week DESC) as rn
|
||||
FROM weekly_report_mv
|
||||
WHERE
|
||||
(report_year < EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER)
|
||||
OR (report_year = EXTRACT(ISOYEAR FROM CURRENT_DATE)::INTEGER
|
||||
AND report_week < EXTRACT(WEEK FROM CURRENT_DATE)::INTEGER)
|
||||
) sub
|
||||
JOIN projects p ON p.id = sub.project_id
|
||||
WHERE rn <= 4 AND p.deleted = FALSE
|
||||
GROUP BY p.id, p.user_id
|
||||
WITH DATA;
|
||||
|
||||
CREATE INDEX idx_projects_median_mv_project_id ON projects_median_mv(project_id);
|
||||
CREATE INDEX idx_projects_median_mv_user_id ON projects_median_mv(user_id);
|
||||
|
||||
COMMENT ON MATERIALIZED VIEW projects_median_mv IS 'Materialized view calculating median score for each project based on last 4 weeks of historical data. Includes user_id for multi-tenant support.';
|
||||
|
||||
ALTER TABLE weekly_goals DROP COLUMN IF EXISTS max_score;
|
||||
Reference in New Issue
Block a user