Salta el contingut

Great Expectations: el framework professional de validació

Great Expectations (GE) és la llibreria de Data Quality més completa de l'ecosistema Python, i s'ha convertit en l'estàndard de facto de la indústria. A diferència dels validadors escrits a mà o de Pandera (pàgina anterior), GE tracta la validació com una entitat de primera classe amb el seu propi vocabulari, amb capacitat de generar automàticament informes HTML navegables i d'integrar-se amb múltiples fonts de dades (pandas, SQL, Spark).


Conceptes principals

Concepte Què és
Expectation Una afirmació sobre les dades que ha de ser certa: expect_column_values_to_not_be_null("email"), expect_column_values_to_be_between("edat", 0, 120).
Expectation Suite Un conjunt d'expectatives aplicades a un dataset concret.
Data Source / Batch La font de dades (un DataFrame, una taula SQL...) i el subconjunt concret ("lot") que es valida.
Validation Definition La combinació d'un lot de dades i una suite d'expectatives.
Checkpoint L'objecte executable que llança una o més validation definitions i en recull el resultat.
Data Docs L'informe HTML generat automàticament que mostra, expectativa per expectativa, quines han passat i quines han fallat.
flowchart LR
    A["Font de dades\n(DataFrame, SQL, Spark)"] --> B["Batch\n(lot a validar)"]
    B --> C["Expectation Suite\n(conjunt de regles)"]
    C --> D["Validation\n(execució)"]
    D --> E["Data Docs\n(informe HTML)"]

    style A fill:#1d4ed8,color:#ffffff,stroke:#3b82f6
    style B fill:#7c3aed,color:#ffffff,stroke:#a78bfa
    style C fill:#b45309,color:#ffffff,stroke:#f59e0b
    style D fill:#166534,color:#ffffff,stroke:#22c55e
    style E fill:#9d174d,color:#ffffff,stroke:#ec4899

Exemple complet de validació amb GE 0.18+

import great_expectations as gx
import pandas as pd

df = pd.read_csv("/dades/vendes_2026_06.csv")

# Context de GE en mode in-memory, sense fitxers de configuració
context = gx.get_context(mode="ephemeral")

# Font de dades i lot a validar
font = context.data_sources.add_pandas("vendes_pandas")
actiu = font.add_dataframe_asset("vendes_juny")
lot = actiu.add_batch_definition_whole_dataframe("lot_complet")

# Suite d'expectatives
suite = context.suites.add(gx.ExpectationSuite(name="suite_vendes"))

suite.add_expectation(gx.expectations.ExpectColumnToExist(column="id_venda"))
suite.add_expectation(gx.expectations.ExpectColumnValuesToNotBeNull(column="id_venda"))
suite.add_expectation(gx.expectations.ExpectColumnValuesToBeUnique(column="id_venda"))
suite.add_expectation(
    gx.expectations.ExpectColumnValuesToBeBetween(
        column="import", min_value=0.01, max_value=99999.99,
    )
)
suite.add_expectation(
    gx.expectations.ExpectColumnValuesToMatchRegex(
        column="email_client",
        regex=r"^[^@]+@[^@]+\.[^@]+$",
        mostly=0.95,   # accepta fins a un 5% de valors invàlids
    )
)
suite.add_expectation(
    gx.expectations.ExpectTableRowCountToBeBetween(min_value=100, max_value=1_000_000)
)

# Execució de la validació
lot_executat = lot.get_batch(batch_parameters={"dataframe": df})
resultat = context.run_validations(
    validation_definition=context.validation_definitions.add(
        gx.ValidationDefinition(name="validacio_vendes", data=lot, suite=suite)
    )
)

if resultat.success:
    print("Totes les expectatives han passat.")
else:
    print("Hi ha expectatives fallides:")
    for res in resultat.results:
        if not res.success:
            print(f"  - {res.expectation_config.type}: {res.result}")
    raise RuntimeError("Validació fallida. Pipeline aturat.")

El paràmetre mostly=0.95 és una de les característiques més útils de GE: permet definir un llindar de tolerància ("com a mínim el 95% dels valors han de complir la regla") en lloc d'una validació estrictament binària, cosa que reflecteix millor la realitat de dades del món real, on un percentatge petit d'excepcions legítimes és normal.


Great Expectations vs Pandera vs dbt tests

Les tres eines validen dades, però en punts diferents de l'arquitectura i amb filosofies diferents:

Pandera Great Expectations dbt tests
On s'executa Dins del codi Python del pipeline Com a pas independent (Python) Dins del Data Warehouse (SQL)
Format de definició Codi Python (DataFrameSchema) Codi Python o configuració declarativa YAML + SQL
Genera informe HTML No (només failure_cases) Sí, automàtic (Data Docs) Sí, amb dbt docs generate
Encaix natural Pipelines pandas ja existents Validació com a producte transversal, multi-font Capa de transformació ELT dins el DW
Corba d'aprenentatge Baixa Mitjana-alta Baixa si ja es coneix dbt

En un pipeline complet no cal triar-ne només una: és habitual validar amb GE (o Pandera) just després de la ingesta, i afegir tests de dbt sobre els models ja transformats dins el Data Warehouse, com a segona xarxa de seguretat:

# models/marts/vendes_resum_diari.yml
version: 2

models:
  - name: vendes_resum_diari
    columns:
      - name: pais
        tests:
          - not_null
          - accepted_values:
              values: ["ES", "FR", "DE", "IT", "PT"]
      - name: import_total
        tests:
          - not_null
          - dbt_utils.expression_is_true:
              expression: ">= 0"
dbt run    # construeix els models
dbt test   # executa els tests declarats al YAML

GE i dbt tests no competeixen, es complementen

GE (o Pandera) protegeix l'entrada del pipeline: dades que no haurien ni d'arribar al Data Warehouse. Els tests de dbt protegeixen la sortida de les transformacions: que un JOIN mal fet o una regla de negoci incorrecta no hagi introduït un problema després que les dades ja fossin vàlides a l'origen. Els dos nivells de defensa cobreixen riscos diferents.


Mòdul M5074 Sistemes de Big Data | Institut Sa Palomera (Blanes) | Curs CEIABD 2026-2027