refactor(sql): reorganize sql files into structured directory hierarchy
Move DDL files from flat ddl/ directory to sql/ddl/ with layer-based subdirectories (stg, ods, dds, dm). Move batch transformation SQL from jobs/ to sql/ layer directories. Update scripts and documentation to reflect new paths for improved organization and Airflow integration.
This commit is contained in:
@@ -21,15 +21,14 @@
|
|||||||
|
|
||||||
### Исполняемые файлы (текущая структура)
|
### Исполняемые файлы (текущая структура)
|
||||||
- `dags/` — Airflow DAGs для оркестрации ETL
|
- `dags/` — Airflow DAGs для оркестрации ETL
|
||||||
- `ddl/` — SQL для создания объектов БД:
|
- `sql/` — SQL по слоям:
|
||||||
- `00_databases.sql` — создание БД stg/ods/dds/dm
|
- `sql/ddl/00_databases.sql` — создание БД stg/ods/dds/dm
|
||||||
- `10_stg.sql` — STG слой (Kafka Engine + MV)
|
- `sql/ddl/stg/10_stg.sql` — STG слой (Kafka Engine + MV)
|
||||||
- `20_ods.sql` — ODS слой (типизация + MV для ошибок)
|
- `sql/ddl/ods/20_ods.sql` — ODS слой (типизация + MV для ошибок)
|
||||||
- `30_dds.sql` — DDS слой (таблицы для batch-загрузки)
|
- `sql/ddl/dds/30_dds.sql` — DDS слой (таблицы для batch-загрузки)
|
||||||
- `40_dm.sql` — DM слой (витрины VIEW)
|
- `sql/ddl/dm/40_dm.sql` — DM слой (витрины VIEW)
|
||||||
- `jobs/` — batch-трансформации:
|
- `sql/dds/30_ods_to_dds.sql` — ODS → DDS (argMax + JOIN)
|
||||||
- `30_dds_refresh.sql` — ODS → DDS (argMax + JOIN)
|
- `sql/dm/40_dds_to_dm.sql` — обновление DQ_summary
|
||||||
- `40_dm_refresh.sql` — обновление DQ_summary
|
|
||||||
- `scripts/` — скрипты автоматизации:
|
- `scripts/` — скрипты автоматизации:
|
||||||
- `apply_clickhouse_ddl.sh` — применение DDL
|
- `apply_clickhouse_ddl.sh` — применение DDL
|
||||||
- `load_kafka_data.sh` — загрузка в Kafka
|
- `load_kafka_data.sh` — загрузка в Kafka
|
||||||
@@ -57,7 +56,7 @@
|
|||||||
Базовые команды:
|
Базовые команды:
|
||||||
|
|
||||||
- `make up` (или `docker compose up -d`)
|
- `make up` (или `docker compose up -d`)
|
||||||
- `make ddl` (применяет SQL из `ddl/*.sql` в ClickHouse)
|
- `make ddl` (применяет SQL из `sql/ddl/00_databases.sql` и `sql/ddl/*/*.sql` в ClickHouse)
|
||||||
- `make data` (пересоздаёт топики и заливает небольшой срез данных в Kafka; полный режим — `FULL=1 make data`)
|
- `make data` (пересоздаёт топики и заливает небольшой срез данных в Kafka; полный режим — `FULL=1 make data`)
|
||||||
- `make transform` (запускает batch-процесс ODS → DDS → DM)
|
- `make transform` (запускает batch-процесс ODS → DDS → DM)
|
||||||
- `docker compose up -d`
|
- `docker compose up -d`
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
- **Комментарии в коде — на русском языке**:
|
- **Комментарии в коде — на русском языке**:
|
||||||
- SQL: заголовочный блок с описанием файла, комментарии к каждому логическому блоку
|
- SQL: заголовочный блок с описанием файла, комментарии к каждому логическому блоку
|
||||||
- Bash: шапка с назначением/запуском/требованиями, секции разделены `# -----`
|
- Bash: шапка с назначением/запуском/требованиями, секции разделены `# -----`
|
||||||
- См. существующие файлы как пример (`ddl/20_ods.sql`, `jobs/30_dds_refresh.sql`, `scripts/run_batch.sh`)
|
- См. существующие файлы как пример (`sql/ddl/ods/20_ods.sql`, `sql/dds/30_ods_to_dds.sql`, `scripts/run_batch.sh`)
|
||||||
|
|
||||||
## Быстрые проверки
|
## Быстрые проверки
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,15 @@ flowchart TB
|
|||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── dags/ # Airflow DAGs для оркестрации
|
├── dags/ # Airflow DAGs для оркестрации
|
||||||
├── ddl/ # SQL для создания объектов (00_databases → 40_dm)
|
├── sql/
|
||||||
├── jobs/ # Batch-трансформации (ODS→DDS, DDS→DM)
|
│ ├── ddl/ # DDL по слоям
|
||||||
|
│ │ ├── 00_databases.sql
|
||||||
|
│ │ ├── stg/10_stg.sql
|
||||||
|
│ │ ├── ods/20_ods.sql
|
||||||
|
│ │ ├── dds/30_dds.sql
|
||||||
|
│ │ └── dm/40_dm.sql
|
||||||
|
│ ├── dds/ # Batch SQL: ODS -> DDS
|
||||||
|
│ └── dm/ # Batch SQL: DDS -> DM
|
||||||
├── scripts/ # Автоматизация (apply ddl, load data, run batch)
|
├── scripts/ # Автоматизация (apply ddl, load data, run batch)
|
||||||
├── airflow/ # Конфигурация Airflow
|
├── airflow/ # Конфигурация Airflow
|
||||||
│ └── requirements.txt
|
│ └── requirements.txt
|
||||||
|
|||||||
@@ -369,11 +369,11 @@ sequenceDiagram
|
|||||||
K-->>User: ✅ Инфраструктура готова
|
K-->>User: ✅ Инфраструктура готова
|
||||||
|
|
||||||
User->>Make: make ddl
|
User->>Make: make ddl
|
||||||
Make->>CH: ddl/00_databases.sql
|
Make->>CH: sql/ddl/00_databases.sql
|
||||||
Make->>CH: ddl/10_stg.sql (Kafka Engine)
|
Make->>CH: sql/ddl/stg/10_stg.sql (Kafka Engine)
|
||||||
Make->>CH: ddl/20_ods.sql (MV)
|
Make->>CH: sql/ddl/ods/20_ods.sql (MV)
|
||||||
Make->>CH: ddl/30_dds.sql
|
Make->>CH: sql/ddl/dds/30_dds.sql
|
||||||
Make->>CH: ddl/40_dm.sql
|
Make->>CH: sql/ddl/dm/40_dm.sql
|
||||||
CH-->>User: ✅ Структура БД создана
|
CH-->>User: ✅ Структура БД создана
|
||||||
|
|
||||||
User->>Make: make data
|
User->>Make: make data
|
||||||
@@ -389,10 +389,10 @@ sequenceDiagram
|
|||||||
CH-->>User: ✅ Данные в STG/ODS
|
CH-->>User: ✅ Данные в STG/ODS
|
||||||
|
|
||||||
User->>Make: make transform
|
User->>Make: make transform
|
||||||
Make->>CH: jobs/30_dds_refresh.sql
|
Make->>CH: sql/dds/30_ods_to_dds.sql
|
||||||
CH->>ODS: argMax() — снапшот
|
CH->>ODS: argMax() — снапшот
|
||||||
CH->>DDS: JOIN + INSERT
|
CH->>DDS: JOIN + INSERT
|
||||||
Make->>CH: jobs/40_dm_refresh.sql
|
Make->>CH: sql/dm/40_dds_to_dm.sql
|
||||||
CH->>DM: DQ summary
|
CH->>DM: DQ summary
|
||||||
CH-->>User: ✅ DDS/DM обновлены
|
CH-->>User: ✅ DDS/DM обновлены
|
||||||
```
|
```
|
||||||
|
|||||||
+10
-10
@@ -7,7 +7,7 @@
|
|||||||
- В `AGENTS.md` как quick check ожидается DAG `etl_pipeline`.
|
- В `AGENTS.md` как quick check ожидается DAG `etl_pipeline`.
|
||||||
- В Airflow-контейнере сейчас нет Kafka CLI, поэтому `kafka-topics.sh` и `kafka-console-producer.sh` из `BashOperator` не используем.
|
- В Airflow-контейнере сейчас нет Kafka CLI, поэтому `kafka-topics.sh` и `kafka-console-producer.sh` из `BashOperator` не используем.
|
||||||
- DDL должен выполняться строго последовательно: `00 -> 10 -> 20 -> 30 -> 40`.
|
- DDL должен выполняться строго последовательно: `00 -> 10 -> 20 -> 30 -> 40`.
|
||||||
- Файл `jobs/30_dds_refresh.sql` уже включает обе загрузки (`dds.click` и `dds.event`), поэтому в MVP это одна task.
|
- Файл `sql/dds/30_ods_to_dds.sql` уже включает обе загрузки (`dds.click` и `dds.event`), поэтому в MVP это одна task.
|
||||||
|
|
||||||
## Архитектура оркестрации
|
## Архитектура оркестрации
|
||||||
### DAG 1 (обязательный): `ddl_init`
|
### DAG 1 (обязательный): `ddl_init`
|
||||||
@@ -44,11 +44,11 @@
|
|||||||
| Task ID | Что делает | Источник SQL/реализация |
|
| Task ID | Что делает | Источник SQL/реализация |
|
||||||
|---------|------------|--------------------------|
|
|---------|------------|--------------------------|
|
||||||
| `check_clickhouse` | Проверка доступности CH (`SELECT 1`) | `PythonOperator` + `clickhouse-connect` |
|
| `check_clickhouse` | Проверка доступности CH (`SELECT 1`) | `PythonOperator` + `clickhouse-connect` |
|
||||||
| `ddl_00_databases` | Создание БД | `ddl/00_databases.sql` |
|
| `ddl_00_databases` | Создание БД | `sql/ddl/00_databases.sql` |
|
||||||
| `ddl_10_stg` | STG + Kafka Engine + MV | `ddl/10_stg.sql` |
|
| `ddl_10_stg` | STG + Kafka Engine + MV | `sql/ddl/stg/10_stg.sql` |
|
||||||
| `ddl_20_ods` | ODS + MV STG→ODS + *_errors | `ddl/20_ods.sql` |
|
| `ddl_20_ods` | ODS + MV STG→ODS + *_errors | `sql/ddl/ods/20_ods.sql` |
|
||||||
| `ddl_30_dds` | Таблицы DDS | `ddl/30_dds.sql` |
|
| `ddl_30_dds` | Таблицы DDS | `sql/ddl/dds/30_dds.sql` |
|
||||||
| `ddl_40_dm` | VIEW витрины DM | `ddl/40_dm.sql` |
|
| `ddl_40_dm` | VIEW витрины DM | `sql/ddl/dm/40_dm.sql` |
|
||||||
| `verify_schema` | Проверка ключевых таблиц/VIEW | SQL-check |
|
| `verify_schema` | Проверка ключевых таблиц/VIEW | SQL-check |
|
||||||
|
|
||||||
Зависимости:
|
Зависимости:
|
||||||
@@ -113,14 +113,14 @@ precheck >> prepare_topics >> [load_browser_events, load_location_events, load_d
|
|||||||
| `check_ods_quality` | Базовые DQ-метрики ODS (ошибки/total) | SQL-check |
|
| `check_ods_quality` | Базовые DQ-метрики ODS (ошибки/total) | SQL-check |
|
||||||
| `truncate_dds_click` | Очистка `dds.click` при `full_refresh=true` | inline SQL |
|
| `truncate_dds_click` | Очистка `dds.click` при `full_refresh=true` | inline SQL |
|
||||||
| `truncate_dds_event` | Очистка `dds.event` при `full_refresh=true` | inline SQL |
|
| `truncate_dds_event` | Очистка `dds.event` при `full_refresh=true` | inline SQL |
|
||||||
| `refresh_dds` | ODS → DDS | `jobs/30_dds_refresh.sql` |
|
| `load_dds` | ODS → DDS | `sql/dds/30_ods_to_dds.sql` |
|
||||||
| `check_dds_integrity` | Проверка orphan событий | inline SQL |
|
| `check_dds_integrity` | Проверка orphan событий | inline SQL |
|
||||||
| `refresh_dm_summary` | DDS → DM DQ summary | `jobs/40_dm_refresh.sql` |
|
| `load_dm_summary` | DDS → DM DQ summary | `sql/dm/40_dds_to_dm.sql` |
|
||||||
| `validate_dm_summary` | Проверка, что `dm.dq_summary` не пуста | SQL-check |
|
| `validate_dm_summary` | Проверка, что `dm.dq_summary` не пуста | SQL-check |
|
||||||
|
|
||||||
Зависимости:
|
Зависимости:
|
||||||
```text
|
```text
|
||||||
wait_for_ods_data >> check_ods_quality >> [truncate_dds_click, truncate_dds_event] >> refresh_dds >> check_dds_integrity >> refresh_dm_summary >> validate_dm_summary
|
wait_for_ods_data >> check_ods_quality >> [truncate_dds_click, truncate_dds_event] >> load_dds >> check_dds_integrity >> load_dm_summary >> validate_dm_summary
|
||||||
```
|
```
|
||||||
|
|
||||||
### Итоговая цепочка `etl_pipeline`
|
### Итоговая цепочка `etl_pipeline`
|
||||||
@@ -230,5 +230,5 @@ docker compose exec -T clickhouse clickhouse-client --user=default --password=12
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Следующий шаг после MVP
|
## Следующий шаг после MVP
|
||||||
- Разделить `jobs/30_dds_refresh.sql` на два файла и распараллелить `refresh_dds_click` и `refresh_dds_event`.
|
- Разделить `sql/dds/30_ods_to_dds.sql` на два файла и распараллелить `load_dds_click` и `load_dds_event`.
|
||||||
- Перейти с `full_refresh` на watermark-инкремент.
|
- Перейти с `full_refresh` на watermark-инкремент.
|
||||||
|
|||||||
+13
-13
@@ -114,32 +114,32 @@ flowchart LR
|
|||||||
|
|
||||||
## План актуализации DDL (target state репозитория)
|
## План актуализации DDL (target state репозитория)
|
||||||
|
|
||||||
Цель: перестать исполнять DDL из markdown и хранить **исполняемые** DDL в отдельных `ddl/*.sql` (по слоям), чтобы:
|
Цель: перестать исполнять DDL из markdown и хранить **исполняемые** DDL в отдельных `sql/*/*.sql` (по слоям), чтобы:
|
||||||
|
|
||||||
- применять их “тонким раннером” через `clickhouse-client` (через `make ddl`);
|
- применять их “тонким раннером” через `clickhouse-client` (через `make ddl`);
|
||||||
- в будущем легко перенести выполнение в Airflow (1 файл = 1 task, линейные зависимости).
|
- в будущем легко перенести выполнение в Airflow (1 файл = 1 task, линейные зависимости).
|
||||||
|
|
||||||
Важно: Kafka-объекты STG включаем **по умолчанию** (как часть `ddl/10_stg.sql`).
|
Важно: Kafka-объекты STG включаем **по умолчанию** (как часть `sql/ddl/stg/10_stg.sql`).
|
||||||
|
|
||||||
### Артефакты DDL (планируемые файлы)
|
### Артефакты DDL (планируемые файлы)
|
||||||
|
|
||||||
- `ddl/00_databases.sql` — базы `stg/ods/dds/dm`.
|
- `sql/ddl/00_databases.sql` — базы `stg/ods/dds/dm`.
|
||||||
- `ddl/10_stg.sql` — STG raw (`stg.*_raw`) + Kafka source tables (`ENGINE = Kafka`) + MV `Kafka → STG`.
|
- `sql/ddl/stg/10_stg.sql` — STG raw (`stg.*_raw`) + Kafka source tables (`ENGINE = Kafka`) + MV `Kafka → STG`.
|
||||||
- `ddl/20_ods.sql` — ODS таблицы типизации + DQ (`parse_errors`) + MV `STG → ODS` + таблицы `ods_*_errors` для строк с битыми ключами.
|
- `sql/ddl/ods/20_ods.sql` — ODS таблицы типизации + DQ (`parse_errors`) + MV `STG → ODS` + таблицы `ods_*_errors` для строк с битыми ключами.
|
||||||
- `ddl/30_dds.sql` — DDS таблицы (`dds.event`, `dds.click`) **без MV** (только `CREATE TABLE`).
|
- `sql/ddl/dds/30_dds.sql` — DDS таблицы (`dds.event`, `dds.click`) **без MV** (только `CREATE TABLE`).
|
||||||
- `ddl/40_dm.sql` — витрины `VIEW` для Superset (`dm.v_*`).
|
- `sql/ddl/dm/40_dm.sql` — витрины `VIEW` для Superset (`dm.v_*`).
|
||||||
|
|
||||||
BI-ограничения (ресурсы/пользователь) **не выносим в `ddl/*.sql`**: оставляем это только как текст/пример в этом плане, чтобы не смешивать инфраструктуру доступа с DDL витрин.
|
BI-ограничения (ресурсы/пользователь) **не выносим в `sql/*/*.sql`**: оставляем это только как текст/пример в этом плане, чтобы не смешивать инфраструктуру доступа с DDL витрин.
|
||||||
|
|
||||||
### Артефакты batch-трансформаций (планируемые файлы)
|
### Артефакты batch-трансформаций (планируемые файлы)
|
||||||
|
|
||||||
- `jobs/30_dds_refresh.sql` — регулярная батч‑сборка DDS из ODS:
|
- `sql/dds/30_ods_to_dds.sql` — регулярная батч‑сборка DDS из ODS:
|
||||||
- получить “последнюю версию” строк по ключам (`event_id`/`click_id`) через `argMax(..., src_ingest_ts)` (или эквивалент);
|
- получить “последнюю версию” строк по ключам (`event_id`/`click_id`) через `argMax(..., src_ingest_ts)` (или эквивалент);
|
||||||
- выполнить join snapshot’ов и загрузить в `dds.event`/`dds.click` (для демо возможно “full rebuild”; позже — инкрементально).
|
- выполнить join snapshot’ов и загрузить в `dds.event`/`dds.click` (для демо возможно “full rebuild”; позже — инкрементально).
|
||||||
|
|
||||||
### Исполнение DDL (make сейчас / Airflow потом)
|
### Исполнение DDL (make сейчас / Airflow потом)
|
||||||
|
|
||||||
Требования к файлам `ddl/*.sql`:
|
Требования к файлам `sql/*/*.sql`:
|
||||||
|
|
||||||
- идемпотентность (`IF NOT EXISTS`), чтобы повторные прогоны были безопасны;
|
- идемпотентность (`IF NOT EXISTS`), чтобы повторные прогоны были безопасны;
|
||||||
- строгий порядок исполнения: `00 → 10 → 20 → 30 → 40` (из‑за зависимостей MV);
|
- строгий порядок исполнения: `00 → 10 → 20 → 30 → 40` (из‑за зависимостей MV);
|
||||||
@@ -163,11 +163,11 @@ BI-ограничения (ресурсы/пользователь) **не вы
|
|||||||
Текущее “как запускаем” (целевое, для реализации следующим шагом):
|
Текущее “как запускаем” (целевое, для реализации следующим шагом):
|
||||||
|
|
||||||
- `make ddl` вызывает `scripts/apply_clickhouse_ddl.sh`;
|
- `make ddl` вызывает `scripts/apply_clickhouse_ddl.sh`;
|
||||||
- скрипт прогоняет `ddl/*.sql` по порядку через `clickhouse-client --multiquery` внутри контейнера ClickHouse.
|
- скрипт прогоняет `sql/*/*.sql` по порядку через `clickhouse-client --multiquery` внутри контейнера ClickHouse.
|
||||||
|
|
||||||
Batch‑трансформации (целевое, для реализации следующим шагом):
|
Batch‑трансформации (целевое, для реализации следующим шагом):
|
||||||
|
|
||||||
- `make transform` (или аналогичная команда) запускает `jobs/30_dds_refresh.sql` через `clickhouse-client`;
|
- `make transform` (или аналогичная команда) запускает `sql/dds/30_ods_to_dds.sql` через `clickhouse-client`;
|
||||||
- в будущем Airflow будет делать то же самое по расписанию (один job‑SQL = один task).
|
- в будущем Airflow будет делать то же самое по расписанию (один job‑SQL = один task).
|
||||||
|
|
||||||
### Параметры окружения (docker compose)
|
### Параметры окружения (docker compose)
|
||||||
@@ -178,7 +178,7 @@ Batch‑трансформации (целевое, для реализации
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Приложение A: текущий inline DDL (legacy; будет вынесен в `ddl/*.sql`)
|
## Приложение A: текущий inline DDL (legacy; будет вынесен в `sql/*/*.sql`)
|
||||||
|
|
||||||
### 0) Базы данных
|
### 0) Базы данных
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# Скрипт применения DDL в ClickHouse
|
# Скрипт применения DDL в ClickHouse
|
||||||
#
|
#
|
||||||
# Назначение:
|
# Назначение:
|
||||||
# Последовательно применяет SQL-файлы из ddl/*.sql в базу ClickHouse.
|
# Последовательно применяет SQL-файлы из sql/ddl/* в базу ClickHouse.
|
||||||
# Файлы применяются в алфавитном порядке (00 → 10 → 20 → 30 → 40).
|
# Порядок фиксированный: 00 → 10 → 20 → 30 → 40.
|
||||||
#
|
#
|
||||||
# Как запускать:
|
# Как запускать:
|
||||||
# make ddl
|
# make ddl
|
||||||
@@ -22,7 +22,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Директория со скриптом
|
# Директория со скриптом
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
DDL_DIR="${SCRIPT_DIR}/../ddl"
|
SQL_ROOT_DIR="${SCRIPT_DIR}/../sql"
|
||||||
|
|
||||||
# Параметры подключения (можно переопределить через переменные окружения)
|
# Параметры подключения (можно переопределить через переменные окружения)
|
||||||
COMPOSE_BIN="${COMPOSE_BIN:-docker compose}"
|
COMPOSE_BIN="${COMPOSE_BIN:-docker compose}"
|
||||||
@@ -31,7 +31,7 @@ CLICKHOUSE_DB="${CLICKHOUSE_DB:-default}"
|
|||||||
CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}"
|
CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}"
|
||||||
CLICKHOUSE_PASSWORD="${CLICKHOUSE_PASSWORD:-123456}"
|
CLICKHOUSE_PASSWORD="${CLICKHOUSE_PASSWORD:-123456}"
|
||||||
|
|
||||||
echo "Применение DDL из ${DDL_DIR}..."
|
echo "Применение DDL из ${SQL_ROOT_DIR}..."
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Проверка: ClickHouse запущен?
|
# Проверка: ClickHouse запущен?
|
||||||
@@ -45,9 +45,20 @@ fi
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Применение SQL-файлов по порядку
|
# Применение SQL-файлов по порядку
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# shellcheck disable=SC2044
|
DDL_FILES=(
|
||||||
for sql_file in "${DDL_DIR}"/*.sql; do
|
"${SQL_ROOT_DIR}/ddl/00_databases.sql"
|
||||||
if [[ -f "$sql_file" ]]; then
|
"${SQL_ROOT_DIR}/ddl/stg/10_stg.sql"
|
||||||
|
"${SQL_ROOT_DIR}/ddl/ods/20_ods.sql"
|
||||||
|
"${SQL_ROOT_DIR}/ddl/dds/30_dds.sql"
|
||||||
|
"${SQL_ROOT_DIR}/ddl/dm/40_dm.sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
for sql_file in "${DDL_FILES[@]}"; do
|
||||||
|
if [[ ! -f "$sql_file" ]]; then
|
||||||
|
echo "Ошибка: не найден SQL-файл: $sql_file" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Применение: $(basename "$sql_file")"
|
echo "Применение: $(basename "$sql_file")"
|
||||||
${COMPOSE_BIN} exec -T "${CLICKHOUSE_SERVICE}" clickhouse-client \
|
${COMPOSE_BIN} exec -T "${CLICKHOUSE_SERVICE}" clickhouse-client \
|
||||||
--user="${CLICKHOUSE_USER}" \
|
--user="${CLICKHOUSE_USER}" \
|
||||||
@@ -56,7 +67,6 @@ for sql_file in "${DDL_DIR}"/*.sql; do
|
|||||||
--multiquery \
|
--multiquery \
|
||||||
< "$sql_file"
|
< "$sql_file"
|
||||||
echo " ✓ OK"
|
echo " ✓ OK"
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
+19
-4
@@ -3,7 +3,7 @@
|
|||||||
# Скрипт batch-трансформации данных: ODS → DDS → DM
|
# Скрипт batch-трансформации данных: ODS → DDS → DM
|
||||||
#
|
#
|
||||||
# Назначение:
|
# Назначение:
|
||||||
# Запускает SQL-скрипты из jobs/ для преобразования данных между слоями:
|
# Запускает SQL-скрипты из sql/dds и sql/dm для преобразования данных между слоями:
|
||||||
# 1. ODS → DDS : Сборка сущностей из типизированных данных
|
# 1. ODS → DDS : Сборка сущностей из типизированных данных
|
||||||
# 2. DDS → DM : Обновление сводки по качеству данных (dq_summary)
|
# 2. DDS → DM : Обновление сводки по качеству данных (dq_summary)
|
||||||
#
|
#
|
||||||
@@ -24,7 +24,9 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Директория со скриптом
|
# Директория со скриптом
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
JOBS_DIR="${SCRIPT_DIR}/../jobs"
|
SQL_ROOT_DIR="${SCRIPT_DIR}/../sql"
|
||||||
|
DDS_TRANSFORM_SQL="${SQL_ROOT_DIR}/dds/30_ods_to_dds.sql"
|
||||||
|
DM_TRANSFORM_SQL="${SQL_ROOT_DIR}/dm/40_dds_to_dm.sql"
|
||||||
|
|
||||||
# Параметры подключения
|
# Параметры подключения
|
||||||
COMPOSE_BIN="${COMPOSE_BIN:-docker compose}"
|
COMPOSE_BIN="${COMPOSE_BIN:-docker compose}"
|
||||||
@@ -42,6 +44,19 @@ if ! ${COMPOSE_BIN} ps | grep -q "${CLICKHOUSE_SERVICE}"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Проверка: SQL-файлы batch существуют?
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
if [[ ! -f "${DDS_TRANSFORM_SQL}" ]]; then
|
||||||
|
echo "Ошибка: Не найден SQL-файл: ${DDS_TRANSFORM_SQL}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "${DM_TRANSFORM_SQL}" ]]; then
|
||||||
|
echo "Ошибка: Не найден SQL-файл: ${DM_TRANSFORM_SQL}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Проверка: в ODS есть данные?
|
# Проверка: в ODS есть данные?
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -83,7 +98,7 @@ ${COMPOSE_BIN} exec -T "${CLICKHOUSE_SERVICE}" clickhouse-client \
|
|||||||
--user="${CLICKHOUSE_USER}" \
|
--user="${CLICKHOUSE_USER}" \
|
||||||
--password="${CLICKHOUSE_PASSWORD}" \
|
--password="${CLICKHOUSE_PASSWORD}" \
|
||||||
--database="${CLICKHOUSE_DB}" \
|
--database="${CLICKHOUSE_DB}" \
|
||||||
--multiquery < "${JOBS_DIR}/30_dds_refresh.sql"
|
--multiquery < "${DDS_TRANSFORM_SQL}"
|
||||||
|
|
||||||
echo " ✓ DDS обновлён"
|
echo " ✓ DDS обновлён"
|
||||||
|
|
||||||
@@ -105,7 +120,7 @@ ${COMPOSE_BIN} exec -T "${CLICKHOUSE_SERVICE}" clickhouse-client \
|
|||||||
--user="${CLICKHOUSE_USER}" \
|
--user="${CLICKHOUSE_USER}" \
|
||||||
--password="${CLICKHOUSE_PASSWORD}" \
|
--password="${CLICKHOUSE_PASSWORD}" \
|
||||||
--database="${CLICKHOUSE_DB}" \
|
--database="${CLICKHOUSE_DB}" \
|
||||||
--multiquery < "${JOBS_DIR}/40_dm_refresh.sql"
|
--multiquery < "${DM_TRANSFORM_SQL}"
|
||||||
|
|
||||||
echo " ✓ DM обновлён"
|
echo " ✓ DM обновлён"
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
--
|
--
|
||||||
-- Загрузка:
|
-- Загрузка:
|
||||||
-- Batch SQL (не MV!) — для согласованности при late arrivals
|
-- Batch SQL (не MV!) — для согласованности при late arrivals
|
||||||
-- См. jobs/30_dds_refresh.sql
|
-- См. sql/dds/30_ods_to_dds.sql
|
||||||
--
|
--
|
||||||
-- Почему не MV:
|
-- Почему не MV:
|
||||||
-- - MV с JOIN даёт eventual consistency (данные приходят в разное время)
|
-- - MV с JOIN даёт eventual consistency (данные приходят в разное время)
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
--
|
--
|
||||||
-- Для продакшена:
|
-- Для продакшена:
|
||||||
-- - Если тяжёлые агрегации тормозят — материализовать в таблицы
|
-- - Если тяжёлые агрегации тормозят — материализовать в таблицы
|
||||||
-- - См. пример закомментированный в jobs/40_dm_refresh.sql
|
-- - См. пример закомментированный в sql/dm/40_dds_to_dm.sql
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
Reference in New Issue
Block a user