diff --git a/docs/internal/pxf_bookings.md b/docs/internal/pxf_bookings.md new file mode 100644 index 0000000..05d40c7 --- /dev/null +++ b/docs/internal/pxf_bookings.md @@ -0,0 +1,199 @@ +# Временное ТЗ по PXF для чтения данных из bookings (черновик) + +_Этот файл внутренний, удалить перед итоговой сдачей._ + +## 1. Цель и границы + +- Минимальная цель: настроить PXF в контейнере Greenplum так, чтобы из базы `bookings` (Postgres в сервисе `bookings-db`) можно было делать `SELECT` по одной внешней таблице в Greenplum. +- На этом этапе **не** делаем загрузку в постоянные таблицы Greenplum, только чтение и ручные smoke‑проверки. +- Изменения в коде/конфигурации пока планируем «на бумаге»; реализацию и правки `docker-compose.yml`/SQL/DAG делаем отдельным шагом. + +## 2. Архитектура на уровне контейнеров + +- `bookings-db` — Postgres 16, демо‑БД `demo` из репозитория `demodb` (источник). Доступен внутри сети Docker по имени `bookings-db` и порту `5432`. +- `greenplum` — контейнер `woblerr/greenplum:6.27.1` (GPDB 6, Ubuntu 22.04). В нём уже есть: + - Greenplum в режиме singlenode; + - установленный PXF (`/usr/local/pxf`, `pxf version release-6.10.1`); + - стартовый скрипт `/start_gpdb.sh`, который умеет включать PXF по флагу `GREENPLUM_PXF_ENABLE=true`. +- Внешний мир (IDE/pytest) подключается к Greenplum по порту `${GP_PORT}` с хоста, а к `bookings-db` — по порту `${BOOKINGS_DB_PORT}` (см. `.env`). + +## 3. Включение PXF в нашем стенде (дизайн) + +Планируемые изменения (позже будут внесены в `docker-compose.yml`): + +- В сервисе `greenplum` в секцию `environment` добавить: + - `GREENPLUM_PXF_ENABLE: "true"`. +- При первом старте с этим флагом скрипт `/start_gpdb.sh` сделает за нас: + - инициализацию PXF (`pxf cluster prepare`, `pxf cluster register`, `pxf cluster sync`); + - создание расширения `pxf` в базе `${GREENPLUM_DATABASE_NAME}` (у нас это `${GP_DB}`, по умолчанию `gpadmin`); + - запуск `pxf cluster start` и привязку остановки/старта PXF к жизненному циклу Greenplum. +- База конфигов PXF (`PXF_BASE`) будет располагаться в `${GREENPLUM_DATA_DIRECTORY}/pxf`, в нашем compose — это `/data/pxf` на томе `greenplum_data`. + - Важно: `make down` сейчас делает `docker compose down -v`, поэтому при полном сбросе томов будут теряться и данные GP, и конфиги PXF (включая JDBC‑драйвер и `servers/*`). + +## 4. JDBC‑драйвер для Postgres: где и как хранить + +Задача: PXF должен уметь ходить по JDBC в `bookings-db` (Postgres). Для этого нужен PostgreSQL JDBC драйвер (`postgresql-*.jar`). + +Варианты хранения драйвера: + +1. **Коммитить JAR в репозиторий** и монтировать в контейнер. + - Плюсы: стенд самодостаточен, не зависит от внешних скачиваний, повторяемость выше (особенно на офлайн‑машинах или при падении зеркал). + - Минусы: лишний бинарник в учебном репо, периодически нужно обновлять версию. +2. **Скачивать JAR внутрь контейнера один раз вручную** и хранить его в томе `greenplum_data` внутри `PXF_BASE/lib`. + - Плюсы: нет бинарников в Git. + - Минусы: дополнительный шаг для студентов, зависимость от сети, нужно повторять после полного сброса томов. + +Для учебного стенда окончательно выбираем вариант **(1) — JAR в репозитории**: + +- В репозитории заводим каталог, например `pxf/` или `pxf/jdbc/`, и кладём туда файл `postgresql-42.7.3.jar` (конкретная версия будет зафиксирована отдельно). +- В `docker-compose.yml` (на этапе реализации) смонтируем этот JAR внутрь контейнера `greenplum` в каталог `$PXF_BASE/lib`, например: + - `./pxf/postgresql-42.7.3.jar:/data/pxf/lib/postgresql-jdbc.jar:ro`. +- PXF по документации поддерживает размещение JDBC‑драйвера в `$PXF_BASE/lib` (общий для всех серверов) или в `$PXF_BASE/servers//lib` (локальный для сервера). Для простоты используем общий каталог `$PXF_BASE/lib`. +- Для студентов не будет лишних подготовительных шагов: после `make up` и инициализации конфигов PXF драйвер уже на месте. + +Открытый момент: конкретный путь/имя каталога в репозитории (`pxf/`, `docker/pxf/` и т.п.) и точная версия драйвера будут приняты при переходе к реализации; важно только, что JAR хранится в Git и монтируется в `/data/pxf/lib` как read‑only. + +## 5. Сервер PXF для bookings-db (jdbc-site.xml) + +PXF использует концепцию «серверов» (`servers/<имя>`), где для каждого сервера хранится свой конфиг подключения (в т.ч. JDBC). + +План: + +- Создать сервер с именем `bookings-db` (название привязываем к сервису Docker, чтобы не путаться). +- Конфиг лежит в файле: + - `$PXF_BASE/servers/bookings-db/jdbc-site.xml`. +- Внутри прописываем параметры подключения к демо‑БД `demo` в Postgres `bookings-db`. + +Черновой шаблон `jdbc-site.xml` (значения логина/пароля берём из `.env`, блок `BOOKINGS_DB_*`): + +```xml + + + + + jdbc.driver + org.postgresql.Driver + + + + jdbc.url + jdbc:postgresql://bookings-db:5432/demo + + + + jdbc.user + ${BOOKINGS_DB_USER} + + + + jdbc.password + ${BOOKINGS_DB_PASSWORD} + + + +``` + +Замечания: + +- Здесь `${BOOKINGS_DB_USER}` и `${BOOKINGS_DB_PASSWORD}` — просто напоминание, что значения нужно взять из `.env`; в реальном файле будут жёстко записаны строки (допустимо для локального учебного стенда). +- Адрес `bookings-db:5432` — имя сервиса и внутренний порт Postgres внутри сети `docker compose`. Внешний порт (`${BOOKINGS_DB_PORT:-5434}`) здесь не используется. +- После правки конфигурации для надёжности планируем выполнять: + ```bash + pxf cluster sync + pxf cluster restart + ``` + чтобы PXF подхватил новые настройки. + +## 6. Внешняя таблица в Greenplum (только для чтения) + +Задача: завести одну external‑таблицу в Greenplum, которая читает данные из демо‑БД `demo` через PXF/JDBC. + +Дизайн: + +- Имя таблицы в Greenplum: `public.ext_bookings_bookings` (подчёркиваем, что это внешнее представление таблицы `bookings.bookings` из Postgres). +- Схема колонок должна совпадать со схемой исходной таблицы в `demo` (её нужно будет аккуратно выписать отдельным шагом, через `\d bookings.bookings` в `bookings-db`). +- Локация PXF: + - `PROFILE=JDBC` — используем JDBC‑профиль. + - `SERVER=bookings-db` — имя сервера из `jdbc-site.xml`. + +Черновой шаблон DDL (без конкретных типов, заполним позже по реальной схеме): + +```sql +CREATE EXTERNAL TABLE public.ext_bookings_bookings ( + -- TODO: колонки как в bookings.bookings (будет уточнено) +) +LOCATION ('pxf://bookings.bookings?PROFILE=JDBC&SERVER=bookings-db') +FORMAT 'CUSTOM' (formatter='pxfwritable_import'); +``` + +Комментарии: + +- На этапе реализации нужно будет: + - в `bookings-db` посмотреть структуру основного факт‑табличного объекта (скорее всего `bookings.bookings`) и перенести DDL; + - проверить типы дат/чисел, чтобы избежать сюрпризов на стороне GP. +- Для MVP достаточно одной таблицы; позже можно добавить ещё 1–2 внешние таблицы для примеров (например, справочники). + +## 7. План тестирования (без дополнительных make‑таргетов) + +Цель тестов: показать студентам, что PXF настроен корректно и позволяет читать данные; при этом не плодить отдельные `make`‑цели, а использовать уже существующие (`make up`, `make bookings-init`, `make gp-psql`). + +### 7.1. Позитивный сценарий (smoke) + +Предварительные условия: + +- `.env` скопирован из `.env.example` и актуален (`BOOKINGS_DB_*`, `GP_*` выставлены). +- В `docker-compose.yml` включён PXF (`GREENPLUM_PXF_ENABLE=true` в сервисе `greenplum`). +- Для `bookings-db` уже выполнен `make bookings-init` (есть данные в `demo`). + +Шаги (в будущем попадут в `TESTING.md`): + +1. Поднять стенд: + - `make up` + - дождаться healthcheck‑ов `pgmeta` и `greenplum`. +2. (Первый раз) Установить JDBC‑драйвер и настроить сервер: + - зайти в контейнер `greenplum` и под `gpadmin` выполнить команды из раздела 4 и 5 (скачивание JAR, создание `jdbc-site.xml`, `pxf cluster sync && restart`). +3. Зайти в Greenplum: + - `make gp-psql`. +4. Проверить, что расширение PXF присутствует: + - `\dx pxf`. +5. Создать внешнюю таблицу `public.ext_bookings_bookings` (DDL из раздела 6, уже с реальными колонками). +6. Выполнить простые запросы: + - `SELECT COUNT(*) FROM public.ext_bookings_bookings;` + - `SELECT * FROM public.ext_bookings_bookings LIMIT 5;` + +Ожидаемый результат: + +- Запросы выполняются без ошибок, возвращают ненулевое количество строк. +- Структура данных визуально совпадает с данными в `bookings-db` (можно дополнительно открыть `bookings-psql` и сравнить). + +### 7.2. Негативный сценарий (отказ источника) + +Цель: показать, как выглядит ошибка, если источник недоступен, и что с этим делать. + +Шаги: + +1. При работающем стенде остановить только `bookings-db`: + - `docker compose stop bookings-db`. +2. В `make gp-psql` попробовать снова: + - `SELECT 1 FROM public.ext_bookings_bookings LIMIT 1;` + +Ожидаемый результат: + +- Запрос падает с ошибкой подключения к Postgres (через JDBC/pxf). +- В `TESTING.md` планируем добавить короткую подсказку: «если видите ошибку подключения — убедитесь, что запущен сервис `bookings-db` (`docker compose start bookings-db`) и повторите запрос». + +### 7.3. Идея для автоматического smoke‑теста (на будущее) + +На будущее (не в рамках текущего этапа) можно добавить простой e2e‑тест в `tests/`, который: + +- с помощью `psycopg2` коннектится к Greenplum (`GP_*` из `.env`); +- выполняет `SELECT 1 FROM public.ext_bookings_bookings LIMIT 1`; +- помечен как «integration» и запускается только по явному желанию (например, через отдельный маркер или переменную окружения). + +Пока это остаётся идеей: сначала реализуем базовую конфигурацию PXF и ручной smoke‑чек‑лист. + +## 8. Открытые вопросы / TODO + +- Уточнить целевую таблицу(ы) в `demo` для внешнего представления (скорее всего `bookings.bookings`), аккуратно выписать DDL и обновить шаблон из раздела 6. +- Принять окончательное решение по версии JDBC‑драйвера и зафиксировать ссылку в документации (с учётом возможного обновления Postgres 16). +- Решить, хотим ли мы автоматизировать шаги установки драйвера/создания `jdbc-site.xml` через init‑скрипт в `/docker-entrypoint-initdb.d` или оставить их полностью ручными для наглядности.