feat(airflow): подключён официальный провайдер ClickHouse

- Зачем:
  - нужен единый штатный путь исполнения SQL и программных запросов ClickHouse из Airflow.
- Что:
  - добавлен официальный провайдер и подключения типа `clickhouse`.
  - SQL-файлы переданы `SQLExecuteQueryOperator`, а программные запросы — `ClickHouseHook`.
  - разбор заказов собран в одном файле, DDL разделён по задачам, документация и смоук обновлены.
- Проверка:
  - выполнены `make lint` и `make config-test`.
  - собран образ, выполнены `pip check`, `make rebuild-storage`, `make smoke` (21/21), `make check-clickhouse` (10/10) и `make check-services` (7/7).
This commit is contained in:
ddadmin committed 2026-08-22 01:40:56 -04:00
1 parent 587e392220
commit 8d82679bc1
17 files changed
+393 -438

No files matched your search

+17 -13
View File
@@ -450,16 +450,18 @@ kafka_offset)`: смотрят такую таблицу от класса, а
Исполняемые дагами запросы лежат по правилу
`sql/<слой>/<объект>_<роль>.sql`. Слой — слой цели запроса: забор заказов в
сырьё живёт в `sql/stg/orders_raw_load.sql`, две ветви разбора — в `sql/ods/`.
Даг называет файлы, передаёт параметры и задаёт порядок выполнения, но не
хранит текст преобразований. Общий фрагмент начинается с подчёркивания: файл
`sql/ods/_order_wire_contract.sql` сам не исполняется, его включают обе ветви
разбора.
сырьё живёт в `sql/stg/orders_raw_load.sql`, разбор — в
`sql/ods/order_parse.sql`. Даг называет файлы, передаёт параметры и задаёт
порядок выполнения, но не хранит текст преобразований. Два выражения разбора
делят локальный макрос Jinja в том же файле; подключаемого SQL-фрагмента между
ними нет.
Airflow читает и собирает эти файлы штатным шаблонизатором при исполнении
задачи. Каталог `sql/` смонтирован во все его службы только для чтения. Поэтому
обработчик дагов не зависит от наличия SQL на машине при разборе Python, а
планировщик видит те же файлы при исполнении задачи.
SQL-файлы исполняет штатный `SQLExecuteQueryOperator`. При разборе Python-кода
обработчик DAG читает список DDL-файлов, загружает содержимое каждого
названного SQL-файла и кладёт его в сериализованный граф. При исполнении Airflow
разворачивает в этом тексте Jinja; параметры ClickHouse передаются отдельно и
не подставляются строкой. Каталог `sql/` смонтирован во все службы Airflow
только для чтения.
### DDL
@@ -489,8 +491,10 @@ Airflow читает и собирает эти файлы штатным шаб
отладке.
Файлы применяет даг `world_initialize` с ноды 1 отдельной учётной записью
`lifecycle`: всё `ON CLUSTER`, кроме чтеца заказов — он объявлен только на этой
ноде. Перед DDL даг создаёт `hits` с двумя партициями и `orders` с одной
`lifecycle`: один файл — одна последовательная задача
`SQLExecuteQueryOperator`, а выражения внутри разделяет сам оператор. Всё
`ON CLUSTER`, кроме чтеца заказов — он объявлен только на этой ноде. Перед DDL
даг создаёт `hits` с двумя партициями и `orders` с одной
([ADR 0008](../adr/0008-order-ingestion.md)). Этот порядок не даёт `hits`
автоматически создаться с одной партицией. Брокер автосоздание разрешает, а
потребитель librdkafka внутри ClickHouse его не просит. Оба конца измерены;
@@ -532,8 +536,8 @@ Airflow читает и собирает эти файлы штатным шаб
| `dic` | `dic.products` | словарь товаров поверх подложки |
Матвью разбора у заказов нет: срез сырья раскладывают по этим двум целям два
`INSERT SELECT` шага `parse_batch` из файлов `sql/ods/order_load.sql` и
`sql/ods/order_errors_load.sql`.
`INSERT SELECT` одной задачи `parse_batch` из файла
`sql/ods/order_parse.sql`.
Слой DDS и слой DM появляются на следующих этапах; их состав задан разделом
7 мастер-спеки и переносится сюда по мере постройки.