Go to main content
CI/CD per pipeline dati - immagine ufficiale della lezione su GinnyTech, creata da AD

CI/CD for data pipelines

Implement CI/CD for dbt, Airflow, and ETL: automated tests, isolated environments, safe deploys.

AD
Created byAndrii Dyshkantiuk
Lesson 130 / 236Level: AdvancedDuration: 22 minPrerequisites: 1

What you will learn

  • Configurare una pipeline CI/CD per dbt con build sui modelli modificati e schema isolato
  • Preparare staging obbligatorio, canarino su frazione dei dati e rollback atomico prima del deploy

CI/CD for data pipelines

Questa lezione, sul binario ml-tabellare, ti abitua a una verità scomoda: nelle pipeline dati i difetti non si vedono quando li commetti, ma quando qualcun altro legge la dashboard. La CI/CD serve esattamente a questo.

Che cosa significa CI/CD applicata ai dati

La CI/CD per dati blocca modelli difettosi in isolamento con test automatici prima del rilascio in produzione. In una frase: il codice sbagliato non deve mai avere la possibilità di arrivare dove decide qualcuno.

Il flusso del rilascio

  1. Isola ogni modifica in branch e schema di sviluppo separato dalla produzione.
  2. Esegui build e test automatici sui soli modelli modificati a ogni pull request.
  3. Valida in staging per 24 ore prima di promuovere in produzione.
  4. Prepara rollback atomico con revert e rebuild prima di ogni deploy.

Cinque regole che separano un rilascio sicuro da uno manuale

Ogni analista lavora sul proprio schema di sviluppo e mai direttamente su produzione. A ogni pull request scatta una build automatica: se la build fallisce, la modifica non si fonde. Il deploy è progressivo con staging obbligatorio e validazione prima della produzione. Il rollback usa revert Git e rebuild oppure scambio immediato tra ambienti. Infine, la qualità vive dentro la pipeline con test su valori nulli, unicità e valori ammessi che bloccano la fusione se falliscono.

Verdetto: branch isolato, build sui modificati e staging obbligatorio; senza questi tre il rilascio resta manuale.

GitHub Actions configuration for dbt

name: dbt CI
on:
  pull_request:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    environment: ci
    steps:
      - uses: actions/checkout@v3
      - name: Install dbt
        run: pip install dbt-snowflake
      - name: Build modified models
        env:
          SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
          SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
        run: |
          dbt deps
          dbt build --select state:modified+ --target ci \
            --defer --state ./target/

Il flag con stato differito esegue solo i modelli modificati e prende il resto dalla produzione. La pipeline passa da ore a minuti senza perdere copertura.

Orchestrazione, test e canarino

I DAG restano codice versionato con ambienti separati tra sviluppo, staging e produzione. Prima del rilascio i flussi girano in modalità test su dati sintetici. Le modifiche delicate partono su una frazione dei dati con verifica dell’output e poi scalano al totale. Il lineage è il grafo delle dipendenze tra tabelle: lo dichiari per far sì che un cambiamento non rompa tabelle a valle in silenzio.

Verdetto: test su sintetici e canarino su frazione dei dati prima del totale.

SQL example: building a control view

Il pattern crea una base analitica con metrica, segmento e finestra temporale. Così confronti periodi e gruppi senza riscrivere la logica.

WITH base_events AS (
  SELECT
    user_id,
    account_id,
    event_type,
    event_time,
    DATE_TRUNC('week', event_time) AS week,
    source,
    device_type
  FROM events
  WHERE event_time >= CURRENT_DATE - INTERVAL '180 days'
    AND user_id IS NOT NULL
),
weekly_user_metrics AS (
  SELECT
    week,
    user_id,
    COALESCE(source, 'unknown') AS source,
    COALESCE(device_type, 'unknown') AS device_type,
    COUNT(*) AS total_events,
    COUNT(DISTINCT DATE(event_time)) AS active_days,
    COUNT(DISTINCT event_type) AS event_diversity,
    MAX(CASE WHEN event_type IN ('purchase', 'subscribe', 'activation') THEN 1 ELSE 0 END) AS reached_key_outcome
  FROM base_events
  GROUP BY week, user_id, source, device_type
)
SELECT
  week,
  source,
  device_type,
  COUNT(DISTINCT user_id) AS users,
  ROUND(AVG(active_days), 2) AS avg_active_days,
  ROUND(AVG(event_diversity), 2) AS avg_event_diversity,
  ROUND(AVG(reached_key_outcome) * 100, 2) AS key_outcome_rate
FROM weekly_user_metrics
GROUP BY week, source, device_type
ORDER BY week, source, device_type;

Python example: checking stability and anomalies

Il controllo su finestra mobile segnala le variazioni che meritano indagine dopo ogni deploy.


# df contiene: week, segment, users, key_outcome_rate
# key_outcome_rate espresso in percentuale, es. 12.4

df = df.sort_values(['segment', 'week']).copy()
df['previous_rate'] = df.groupby('segment')['key_outcome_rate'].shift(1)
df['wow_change_pp'] = df['key_outcome_rate'] - df['previous_rate']
df['rolling_mean'] = df.groupby('segment')['key_outcome_rate'].transform(
    lambda s: s.rolling(4, min_periods=2).mean()
)
df['rolling_std'] = df.groupby('segment')['key_outcome_rate'].transform(
    lambda s: s.rolling(4, min_periods=2).std()
)
df['z_score'] = (df['key_outcome_rate'] - df['rolling_mean']) / df['rolling_std']

anomalies = df[df['z_score'].abs() >= 2].sort_values('z_score')
print(anomalies[['week', 'segment', 'key_outcome_rate', 'wow_change_pp', 'z_score']])

Quando un aggiornamento fermò mezzo mondo

Il 19 luglio 2024 un aggiornamento difettoso del sensore CrowdStrike Falcon manda in boot loop circa 8,5 milioni di PC Windows nel mondo. Il file viene distribuito senza rilascio graduale e senza blocco automatico, così compagnie aeree, banche e ospedali restano fermi per ore. Il ripristino richiede intervento manuale su ogni macchina colpita. La lezione per la CI/CD dati è identica: nessun artefatto tocca la produzione senza canarino, test e rollback pronto.

Domande per controllare il tuo processo

  1. Quale test blocca la tua pull request se un modello è difettoso?
  2. Quale ambiente isolato separa sviluppo, staging e produzione?
  3. Quale strategia di rollback applichi se il deploy fallisce?
  4. Quale controllo verifica l’output prima di scalare al totale?
Serve una mano concreta?

Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.

Book a call