fix(airflow): исправлен запуск пульта на свежем стенде
- Зачем: - свежий стенд должен доходить до generator_control без скрытых ручных шагов и зависаний. - Что: - quick start явно готовит DDL и откладывает Superset init до готового DM. - generator_control проверяет паузу etl_pipeline до мутирующих шагов. - make up пересобирает Airflow и поднимает базовый набор сервисов. - Проверка: - make generator-test; docker compose config --quiet; make clean; make up; make ddl.
This commit is contained in:
@@ -10,10 +10,13 @@ from __future__ import annotations
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from airflow import DAG
|
||||
from airflow.exceptions import AirflowException
|
||||
from airflow.models.dag import DagModel
|
||||
from airflow.models.param import Param
|
||||
from airflow.operators.empty import EmptyOperator
|
||||
from airflow.operators.python import BranchPythonOperator, PythonOperator
|
||||
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
|
||||
from airflow.utils.session import provide_session
|
||||
from airflow.utils.trigger_rule import TriggerRule
|
||||
from airflow_clickhouse_plugin.hooks.clickhouse import ClickHouseHook
|
||||
|
||||
@@ -41,6 +44,8 @@ default_args = {
|
||||
"retry_delay": timedelta(minutes=1),
|
||||
}
|
||||
|
||||
ETL_DAG_ID = "etl_pipeline"
|
||||
|
||||
|
||||
def _conf(context) -> dict:
|
||||
dag_run = context.get("dag_run")
|
||||
@@ -92,9 +97,9 @@ def choose_operation(**context) -> str:
|
||||
"""Выбирает ветку пульта по параметру operation."""
|
||||
operation = _operation(context)
|
||||
if operation == "backfill":
|
||||
return "precheck_backfill"
|
||||
return "check_etl_not_paused_before_backfill"
|
||||
if operation == "import":
|
||||
return "precheck_import"
|
||||
return "check_etl_not_paused_before_import"
|
||||
if operation == "check":
|
||||
return "check_only"
|
||||
raise ValueError(f"Неизвестная операция: {operation}")
|
||||
@@ -144,6 +149,27 @@ def check_manifest_task(**context) -> None:
|
||||
assert_clickhouse_matches_manifest(manifest, hook)
|
||||
|
||||
|
||||
@provide_session
|
||||
def assert_target_dag_not_paused(dag_id: str, session=None) -> None:
|
||||
"""
|
||||
Проверяет, что зависимый DAG можно запустить.
|
||||
|
||||
Context7: для Airflow 2.10.5 у старого TriggerDagRunOperator нет надёжного
|
||||
fail_when_dag_is_paused, поэтому паузу проверяем заранее через DagModel.
|
||||
"""
|
||||
dag_model = session.query(DagModel).filter(DagModel.dag_id == dag_id).one_or_none()
|
||||
if dag_model is None:
|
||||
raise AirflowException(
|
||||
f"DAG {dag_id} ещё не найден Airflow. Подождите парсинга DAG-файлов "
|
||||
"или перезапустите Airflow через make up."
|
||||
)
|
||||
if dag_model.is_paused:
|
||||
raise AirflowException(
|
||||
f"DAG {dag_id} стоит на паузе: снимите паузу в Airflow UI, "
|
||||
"затем повторите generator_control."
|
||||
)
|
||||
|
||||
|
||||
with DAG(
|
||||
dag_id="generator_control",
|
||||
description="Пульт стартовой истории генератора",
|
||||
@@ -224,9 +250,20 @@ with DAG(
|
||||
python_callable=run_import_task,
|
||||
)
|
||||
|
||||
check_etl_not_paused_before_backfill = PythonOperator(
|
||||
task_id="check_etl_not_paused_before_backfill",
|
||||
python_callable=assert_target_dag_not_paused,
|
||||
op_kwargs={"dag_id": ETL_DAG_ID},
|
||||
)
|
||||
check_etl_not_paused_before_import = PythonOperator(
|
||||
task_id="check_etl_not_paused_before_import",
|
||||
python_callable=assert_target_dag_not_paused,
|
||||
op_kwargs={"dag_id": ETL_DAG_ID},
|
||||
)
|
||||
|
||||
trigger_etl = TriggerDagRunOperator(
|
||||
task_id="trigger_etl",
|
||||
trigger_dag_id="etl_pipeline",
|
||||
trigger_dag_id=ETL_DAG_ID,
|
||||
conf={"full_refresh": True},
|
||||
wait_for_completion=True,
|
||||
allowed_states=["success"],
|
||||
@@ -250,7 +287,13 @@ with DAG(
|
||||
trigger_rule=TriggerRule.NONE_FAILED_MIN_ONE_SUCCESS,
|
||||
)
|
||||
|
||||
route >> [precheck_backfill_task, precheck_import_task, check_only]
|
||||
route >> [
|
||||
check_etl_not_paused_before_backfill,
|
||||
check_etl_not_paused_before_import,
|
||||
check_only,
|
||||
]
|
||||
check_etl_not_paused_before_backfill >> precheck_backfill_task
|
||||
check_etl_not_paused_before_import >> precheck_import_task
|
||||
precheck_backfill_task >> backfill_task >> trigger_etl
|
||||
precheck_import_task >> import_task >> trigger_etl
|
||||
trigger_etl >> check_after_etl >> done
|
||||
|
||||
Reference in New Issue
Block a user