Files
clickstream-ch-kafka-supers…/airflow/dags/world_next_day_dag.py
T
ddadminandClaude Fable 5 ac7a973504 feat(airflow): пульт стал world_init, добавлен DAG world_next_day (#4)
- Зачем:
  - список DAG'ов должен читаться лесенкой ddl_init → world_init →
    world_next_day, а путь менти — проходиться пустыми формами
    (issue #4, спека редизайна пути менти, решения 2–3).
- Что:
  - generator_control переименован в world_init, дефолт операции —
    import; next-day ушёл из выпадашки в отдельный DAG;
  - новый беспараметрный world_next_day: расписание */30 * * * *,
    создаётся на паузе, catchup=False, max_active_runs=1; общие
    задачи вынесены в airflow/dags/utils/startup_history_tasks.py;
  - доки и контрактные тесты обновлены синхронно; быстрый старт
    README — без make ddl, схему создаёт DAG ddl_init.
- Проверка:
  - make test (210 + 31) и make lint зелёные;
  - живая приёмка на чистом стенде: world_init пустой формой
    импортировал эталонный мир за 217 с (3 дня, 280 437 событий),
    world_next_day после снятия с паузы добавляет ровно один день
    за прогон, дашборд Superset собирается.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:45:02 +03:00

70 lines
2.1 KiB
Python

"""DAG добавления одного модельного дня в мир стенда."""
from datetime import datetime, timedelta
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
from utils.startup_history_tasks import (
assert_target_dag_not_paused,
check_manifest_task,
precheck_next_day,
run_next_day_task,
)
ETL_DAG_ID = "etl_pipeline"
default_args = {
"owner": "airflow",
"depends_on_past": False,
"email_on_failure": False,
"email_on_retry": False,
"retries": 0,
"retry_delay": timedelta(minutes=1),
}
# Context7, Airflow 2.10.5: schedule принимает cron-строку. Расписание задано
# заранее, но новый DAG остаётся на паузе до отдельного решения.
with DAG(
dag_id="world_next_day",
description="Добавление одного модельного дня в мир стенда",
default_args=default_args,
schedule="*/30 * * * *",
start_date=datetime(2024, 1, 1),
catchup=False,
max_active_runs=1,
is_paused_upon_creation=True,
tags=["generator", "startup-history"],
) as dag:
check_etl_not_paused = PythonOperator(
task_id="check_etl_not_paused",
python_callable=assert_target_dag_not_paused,
op_kwargs={"dag_id": ETL_DAG_ID},
)
precheck = PythonOperator(
task_id="precheck_next_day",
python_callable=precheck_next_day,
)
generate = PythonOperator(
task_id="run_next_day",
python_callable=run_next_day_task,
)
trigger_etl = TriggerDagRunOperator(
task_id="trigger_etl",
trigger_dag_id=ETL_DAG_ID,
conf={"full_refresh": True},
wait_for_completion=True,
allowed_states=["success"],
failed_states=["failed"],
poke_interval=30,
)
check = PythonOperator(
task_id="check_after_etl",
python_callable=check_manifest_task,
)
check_etl_not_paused >> precheck >> generate >> trigger_etl >> check