Nightly ETL: extract, transform, load как шаги пайплайна без Airflow
Три шага пайплайна: extract (запрос из источников), transform (агрегация, очистка), load (запись в аналитику). Каждый шаг повторяется независимо при ошибке — без Airflow и отдельного воркера.
Last updated: 2026-04-20
Answer first
Direct answer
Nightly ETL: extract, transform, load как шаги пайплайна без Airflow. Extract, transform, load — три функции в пайплайне с явными зависимостями. Сбой в load → повтор только load без повторного extract.
When it fits
- ETL до 10 шагов без сложных DAG с циклами
- Нужны step-level повторы без Airflow-деплоя
Tradeoffs
- Один большой cron-скрипт без step-изоляции: частичный сбой = неизвестное состояние данных. Нет понимания, до какого шага дошло.
- Без idempotent load повторный прогон из-за ретрая дублирует аналитические строки.
Нагрузка и где ломается
Почему ETL сложен без managed пайплайна
- Airflow: powerful DAG orchestration, but a Kubernetes cluster or managed cloud service to maintain
- Prefect / Dagster: better developer experience than Airflow, but still requires a separate deployment
- crontab: simple but no run history, no retries, no dependency tracking between steps
- Lambda + EventBridge: possible, but step chaining and observability require significant wiring
Airflow, Luigi, Prefect — серьёзные инструменты для больших DAG. Для ночного ETL 3–5 шагов это overhead: отдельный деплой, отдельный мониторинг, scheduler-воркер.
Где костыли не спасают
Где ломаются простые ETL скрипты
Один большой cron-скрипт без step-изоляции: частичный сбой = неизвестное состояние данных. Нет понимания, до какого шага дошло.
Без idempotent load повторный прогон из-за ретрая дублирует аналитические строки.
Как помогает Inquir
ETL как шаги пайплайна
Extract, transform, load — три функции в пайплайне с явными зависимостями. Сбой в load → повтор только load без повторного extract.
История каждого прогона в консоли: какой шаг упал, сколько строк обработано, когда запустился следующий прогон.
Что получаете
Что нужно для надёжного nightly ETL
Step-level изоляция
Extract, transform, load — отдельные функции. Повтор только упавшего шага.
Idempotent load
`TRUNCATE + INSERT` или `UPSERT ON CONFLICT` — повторный прогон даёт тот же результат.
История прогонов
Каждый cron-прогон — запись с логами шагов. Видно, сколько строк извлечено, трансформировано, загружено.
Зависимости шагов
Transform стартует только после успешного Extract. Load — только после Transform.
Что делать дальше
Как организовать nightly ETL
Extract
Запросить данные из источников (DB, API, файлы) за прошедшие сутки.
Transform
Агрегация, очистка, обогащение. Результат — промежуточный файл или таблица.
Load
Idempotent запись в аналитическое хранилище: TRUNCATE+INSERT или MERGE.
Пример кода
Nightly ETL: API → transform → Postgres
Cron triggers nightly at 02:00 UTC. Extract step fetches, transform step normalizes, load step upserts. Each step retries independently.
export async function handler(event) { const date = new Date().toISOString().slice(0, 10); // YYYY-MM-DD const records = await externalApi.fetchDailyReport(date); // Store to object storage — pipeline passes storage key to next step const key = `etl/raw/${date}.json`; await storage.putJson(key, records); return { key, count: records.length, date }; }
export async function handler(event) { const { key, date } = event.previousOutput ?? {}; const raw = await storage.getJson(key); const transformed = raw.map((r) => ({ id: r.external_id, date, revenue: parseFloat(r.revenue_usd), region: r.region?.toLowerCase(), updatedAt: new Date().toISOString(), })); const outKey = `etl/transformed/${date}.json`; await storage.putJson(outKey, transformed); return { outKey, count: transformed.length, date }; }
Когда подходит
Когда Inquir подходит для ETL
Когда это уместно
- ETL до 10 шагов без сложных DAG с циклами
- Нужны step-level повторы без Airflow-деплоя
Когда лучше не трогать
- ETL с десятками взаимозависимых задач, динамическим DAG — Airflow/Prefect мощнее
FAQ
Вопросы и ответы
Как передать данные между шагами?
Через объектное хранилище (S3 key в payload пайплайна) или через базу с промежуточной таблицей.
Поддерживаются параллельные шаги extract?
Да. Несколько шагов без `dependsOn` выполняются параллельно — извлечение из нескольких источников одновременно.