-- Preflight (только чтение): переход progress-миграции профиля V10 -> V13. -- Проверяет историю Flyway, тип/nullable колонок и валидность индекса. -- Ничего не изменяет: DELETE в конце приведён только как закомментированный пример. -- Пример: -- psql -h localhost -U lms -d lms -f deploy/preflight/progress-v10-v13.sql \set ON_ERROR_STOP on \pset pager off \echo '=== 0. Наличие progress.flyway_schema_history ===' SELECT to_regclass('progress.flyway_schema_history') IS NOT NULL AS progress_flyway_schema_history_exists \gset \if :progress_flyway_schema_history_exists \echo '=== 1. progress.flyway_schema_history: версии 10-13 ===' SELECT installed_rank, version, description, type, script, success, installed_on FROM progress.flyway_schema_history WHERE version IN ('10', '11', '12', '13') ORDER BY installed_rank; \else \echo 'progress.flyway_schema_history не найдена: сервис ещё не применял миграции progress.' \echo 'Проверьте LMS_DB_URL / схему progress и повторите preflight.' \endif \echo '=== 2. Колонки профиля: тип uuid и nullable (ok = true) ===' SELECT expected.table_name, expected.column_name, c.data_type, c.is_nullable, (c.data_type = 'uuid' AND c.is_nullable = 'YES') AS ok FROM (VALUES ('grade_comments', 'author_account_id'), ('lab_grades', 'updated_by_account_id') ) AS expected(table_name, column_name) LEFT JOIN information_schema.columns c ON c.table_schema = 'progress' AND c.table_name = expected.table_name AND c.column_name = expected.column_name ORDER BY expected.table_name, expected.column_name; \echo '=== 3. Индекс lab_grades_lab_idx: существует, валиден, определение ===' SELECT i.indexrelid::regclass AS index_name, i.indisvalid, i.indisready, pg_get_indexdef(i.indexrelid) AS definition FROM pg_index i JOIN pg_class idx ON idx.oid = i.indexrelid JOIN pg_namespace n ON n.oid = idx.relnamespace WHERE n.nspname = 'progress' AND idx.relname = 'lab_grades_lab_idx'; \echo '=== 4. Сводка: колонки и индекс готовы к V13 ===' SELECT ( SELECT count(*) = 2 AND bool_and(c.data_type = 'uuid' AND c.is_nullable = 'YES') FROM information_schema.columns c WHERE c.table_schema = 'progress' AND (c.table_name, c.column_name) IN ( ('grade_comments', 'author_account_id'), ('lab_grades', 'updated_by_account_id') ) ) AS columns_ok, ( SELECT count(*) = 1 AND bool_and(i.indisvalid) FROM pg_index i JOIN pg_class idx ON idx.oid = i.indexrelid JOIN pg_namespace n ON n.oid = idx.relnamespace WHERE n.nspname = 'progress' AND idx.relname = 'lab_grades_lab_idx' ) AS index_ok; -- Очистка истории (НЕ выполняется этим скриптом). -- -- Если старая feature-миграция V10 применена со success=true, удалите ТОЛЬКО -- её запись истории: объекты схемы уже созданы, а V13 идемпотентна и создаст -- недостающие колонки/индекс. Гард по RETURNING: ожидается ровно одна строка; -- если строк больше или меньше — ROLLBACK. -- -- BEGIN; -- DELETE FROM progress.flyway_schema_history -- WHERE version = '10' -- AND script = 'V10__profile_authors.sql' -- AND success -- RETURNING installed_rank, version, script, success; -- -- expect exactly one row; otherwise ROLLBACK -- COMMIT; -- -- Если V10 осталась со success=false, сначала убедитесь, что её частичные -- изменения откатились на уровне объектов, затем выполните `flyway repair` -- или удалите только неуспешную строку. V13 идемпотентна и досоздаст -- недостающие объекты. Перед удалением строки запустите этот preflight: -- все проверки должны быть true. -- -- Не переставляйте V11/V12 и не включайте out-of-order.