feat(airflow): добавлен гейт целостности DDS для урока 4

- Зачем:
  - урок 4 должен показывать не только измерение сирот в DDS, но и остановку Airflow DAG при нарушении связи dds.event -> dds.click.
- Что:
  - добавлен assert_dds_integrity в etl_pipeline и документация управляемого красного сценария.
  - вынесены общие helper'ы для SQL-split и boolean-параметров Airflow.
  - добавлен урок 4 и обновлены навигация курса, план обучения и operations notes.
- Проверка:
  - python3 -m py_compile airflow/dags/etl_pipeline_dag.py airflow/dags/ddl_init_dag.py airflow/dags/kafka_load_dag.py airflow/dags/utils/airflow_params.py airflow/dags/utils/sql_helpers.py.
  - docker compose exec -T airflow-webserver airflow dags test etl_pipeline 2026-06-05T18:00:00 -c '{"full_refresh": true}'.
This commit is contained in:
2026-06-05 19:13:22 +03:00
parent 4f1e58752c
commit 707da9f80e
10 changed files with 623 additions and 45 deletions
+33
View File
@@ -0,0 +1,33 @@
"""Общие helper-функции для параметров Airflow DAG."""
from __future__ import annotations
TRUE_VALUES = {"1", "true", "t", "yes", "y", "on"}
FALSE_VALUES = {"0", "false", "f", "no", "n", "off"}
def _param_error(message: str) -> Exception:
try:
from airflow.exceptions import AirflowException
return AirflowException(message)
except ModuleNotFoundError:
return ValueError(message)
def parse_bool_param(value: object, name: str) -> bool:
"""Преобразует bool-параметр из dag_run.conf/params в явный boolean."""
if isinstance(value, bool):
return value
if isinstance(value, int) and value in (0, 1):
return bool(value)
if isinstance(value, str):
normalized = value.strip().lower()
if normalized in TRUE_VALUES:
return True
if normalized in FALSE_VALUES:
return False
raise _param_error(f"Параметр {name} должен быть boolean, получено: {value!r}")