From ffd9585ef46f326dbb7ffe67552ee8a6a9d9eaa3 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sat, 28 Feb 2026 22:00:27 +0300 Subject: [PATCH] =?UTF-8?q?fix(bookings):=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=8F=D0=B2=D0=BD=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20jobs=3D1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - исключить нестабильные режимы генератора, в которых bookings может перестать пополняться. - сделать причину ошибки понятной студенту сразу при запуске команд и SQL-скриптов. - Что: - добавлен precheck `bookings-check-jobs` в Makefile и подключён к `bookings-init` и `bookings-generate-day`. - добавлены явные проверки `bookings.jobs = 1` в `bookings/generate_next_day.sql` и `sql/src/bookings_generate_day_if_missing.sql`. - обновлена документация и `.env.example`: зафиксировано, что в стенде поддерживается только `BOOKINGS_JOBS=1`. - Проверка: - uv run make fmt. - uv run make test. - env BOOKINGS_JOBS=2 make bookings-init. - env BOOKINGS_JOBS=2 make bookings-generate-day. - make bookings-init. - make bookings-generate-day. --- .env.example | 2 +- Makefile | 12 +++++++++--- README.md | 3 +++ bookings/README.md | 3 ++- bookings/generate_next_day.sql | 5 +++++ docs/bookings_to_gp_stage.md | 2 ++ docs/stack.md | 2 +- sql/src/bookings_generate_day_if_missing.sql | 5 +++++ 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index b11df71..a5de38d 100644 --- a/.env.example +++ b/.env.example @@ -24,7 +24,7 @@ BOOKINGS_DB_PORT=5434 BOOKINGS_START_DATE=2017-01-01 # Количество дней для первой генерации (держим малым, чтобы быстрее увидеть данные) BOOKINGS_INIT_DAYS=1 -# Количество параллельных джобов генератора (по умолчанию 1; при 1 работаем синхронно без dblink) +# Количество джобов генератора. В учебном стенде поддерживается только значение 1. BOOKINGS_JOBS=1 # Greenplum Configuration diff --git a/Makefile b/Makefile index bf7f3ec..858994b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ BOOKINGS_START_DATE ?= 2017-01-01 BOOKINGS_INIT_DAYS ?= 1 .PHONY: up stop down clean airflow-init logs gp-psql ddl-gp \ - bookings-clone-demodb bookings-init bookings-psql bookings-generate-day \ + bookings-check-jobs bookings-clone-demodb bookings-init bookings-psql bookings-generate-day \ dev-setup dev-sync dev-lock test lint fmt clean-venv build SHELL := /bin/bash @@ -61,7 +61,13 @@ bookings-clone-demodb: fi; \ fi -bookings-init: bookings-clone-demodb +bookings-check-jobs: + @if [ "$(BOOKINGS_JOBS)" != "1" ]; then \ + echo "Поддерживается только BOOKINGS_JOBS=1. Измените .env и повторите команду." >&2; \ + exit 1; \ + fi + +bookings-init: bookings-check-jobs bookings-clone-demodb docker compose -f docker-compose.yml up -d bookings-db docker compose -f docker-compose.yml exec bookings-db bash -lc '\ until PGPASSWORD="$$POSTGRES_PASSWORD" pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -h localhost; do \ @@ -88,7 +94,7 @@ bookings-init: bookings-clone-demodb bookings-psql: docker compose -f docker-compose.yml exec bookings-db bash -lc 'PGPASSWORD="$$POSTGRES_PASSWORD" psql -U "$$POSTGRES_USER" -d demo' -bookings-generate-day: +bookings-generate-day: bookings-check-jobs docker compose -f docker-compose.yml up -d bookings-db docker compose -f docker-compose.yml exec bookings-db bash -lc '\ until PGPASSWORD="$$POSTGRES_PASSWORD" pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -h localhost; do \ diff --git a/README.md b/README.md index d159861..a59de83 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,8 @@ make up make bookings-init ``` +Важно: генератор `bookings` в этом стенде поддерживается только в режиме `BOOKINGS_JOBS=1`. + 4) Подготовьте STG‑объекты в Greenplum (выберите один вариант): - Учебный вариант: в Airflow UI запустите DAG `bookings_stg_ddl`; @@ -141,6 +143,7 @@ make clean # полный reset: удалить контейнер |----------|---------| | Airflow UI не открывается | Дождитесь сообщения `Listening at: http://0.0.0.0:8080` в логах (`make logs`) | | `database "demo" does not exist` в bookings‑DAG | Вы сделали reset с удалением volumes (`make clean` / `docker compose down -v`). Запустите `make bookings-init` и повторите DAG. | +| `Поддерживается только bookings.jobs=1` или `BOOKINGS_JOBS=1` | В этом учебном стенде поддерживается только синхронный режим генерации. Установите `BOOKINGS_JOBS=1` и выполните `make bookings-init`. | | Ошибка подключения к Greenplum | Убедитесь, что контейнер `greenplum` имеет статус `healthy` (`docker compose ps`) | | `protocol "pxf" does not exist` | Перезапустите `greenplum` и повторите `bookings_stg_ddl`/`make ddl-gp` — расширение `pxf` создаётся автоматически при старте контейнера. | | DAG `bookings_to_gp_stage` ругается на отсутствующие таблицы stg | Запустите `bookings_stg_ddl` (или выполните `make ddl-gp`), затем повторите запуск | diff --git a/bookings/README.md b/bookings/README.md index cce2c2f..30dac82 100644 --- a/bookings/README.md +++ b/bookings/README.md @@ -18,6 +18,7 @@ - `engine.sql`: два изменения в `engine_jobs1_sync.patch`: - `busy()` игнорирует свой `pid`, чтобы не считать собственное подключение занятым; - `continue()` при `jobs=1` вызывает `process_queue` синхронно (без `dblink`), иначе генерация обрывается при выходе из `psql` и данных не появляется. +- Режим эксплуатации в этом стенде: только `jobs=1` (`BOOKINGS_JOBS=1`). - Патчи применяются автоматически в `make bookings-init`. Если что-то пошло не так, их можно накатить вручную: ``` patch -d bookings/demodb -p1 --forward < bookings/patches/install_drop_if_exists.patch @@ -36,6 +37,6 @@ SELECT date_trunc('day', max(book_date)) + interval '1 day' INTO v_next_day FROM bookings.bookings; - CALL continue(v_next_day); -- или CALL continue(v_next_day, 4) + CALL continue(v_next_day, 1); END $$; ``` diff --git a/bookings/generate_next_day.sql b/bookings/generate_next_day.sql index 58afdc8..236c986 100644 --- a/bookings/generate_next_day.sql +++ b/bookings/generate_next_day.sql @@ -14,6 +14,11 @@ BEGIN RAISE EXCEPTION 'Таблица bookings.bookings не найдена. Сначала выполните make bookings-init.'; END IF; + -- В учебном стенде поддерживается только jobs=1, иначе генерация нестабильна. + IF v_jobs <> 1 THEN + RAISE EXCEPTION 'Поддерживается только bookings.jobs=1. Текущее значение: %. Установите BOOKINGS_JOBS=1 и выполните make bookings-init.', v_jobs; + END IF; + -- Ищем последнюю сгенерированную дату SELECT max(book_date) INTO v_max_book_date FROM bookings.bookings; diff --git a/docs/bookings_to_gp_stage.md b/docs/bookings_to_gp_stage.md index 33dba5b..dac1a63 100644 --- a/docs/bookings_to_gp_stage.md +++ b/docs/bookings_to_gp_stage.md @@ -25,6 +25,8 @@ make up make bookings-init ``` +Важно: генератор `bookings` в этом стенде поддерживается только в режиме `BOOKINGS_JOBS=1`. + 3) В Greenplum созданы `stg.bookings_ext` и `stg.bookings` (выберите один вариант): - учебный вариант: запустить DAG `bookings_stg_ddl` в Airflow UI; diff --git a/docs/stack.md b/docs/stack.md index d072424..4a706c6 100644 --- a/docs/stack.md +++ b/docs/stack.md @@ -132,7 +132,7 @@ make fmt - `BOOKINGS_DB_PORT` — внешний порт (по умолчанию `5434`) - `BOOKINGS_START_DATE` — стартовая дата модельного времени - `BOOKINGS_INIT_DAYS` — сколько дней генерировать при первом `make bookings-init` -- `BOOKINGS_JOBS` — число джобов генератора (по умолчанию `1`) +- `BOOKINGS_JOBS` — число джобов генератора; в учебном стенде поддерживается только `1` ### CSV pipeline (побочный пример) diff --git a/sql/src/bookings_generate_day_if_missing.sql b/sql/src/bookings_generate_day_if_missing.sql index 72dd8e8..f493cbc 100644 --- a/sql/src/bookings_generate_day_if_missing.sql +++ b/sql/src/bookings_generate_day_if_missing.sql @@ -17,6 +17,11 @@ BEGIN RAISE EXCEPTION 'Таблица bookings.bookings не найдена. Сначала выполните make bookings-init.'; END IF; + -- В учебном стенде поддерживается только jobs=1, иначе генерация нестабильна. + IF v_jobs <> 1 THEN + RAISE EXCEPTION 'Поддерживается только bookings.jobs=1. Текущее значение: %. Установите BOOKINGS_JOBS=1 и выполните make bookings-init.', v_jobs; + END IF; + -- Ищем последнюю сгенерированную дату SELECT max(book_date) INTO v_max_book_date FROM bookings.bookings;