(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo versionar esquemas en Lakehouse: paso a paso

João Barros 23 de September de 2026 5 min de lectura

Este tutorial muestra cómo implementar versionado de esquemas en Lakehouse para gestionar cambios de esquema en tablas Delta, evitando que pipelines ETL fallen cuando llegan nuevas columnas o tipos distintos. La técnica permite validar, aplicar y revertir cambios de esquema de forma controlada.

Pre-requisitos

  • Cuenta con acceso al Microsoft Fabric/Workspace con permisos para crear Lakehouse y ejecutar notebooks.
  • Conocimientos básicos de Spark/PySpark y Delta Lake.
  • Ejemplo de datos de ingestión en CSV o Parquet y acceso al OneLake/Storage del Lakehouse.

Paso 1: Concepto y estrategia de versionado

Por qué versionar: cambios de esquema (columnas nuevas, eliminadas o tipo distinto) pueden romper consumos y jobs. La estrategia sencilla es mantener un archivo de esquema por versión (JSON), validar la entrada, aplicar una transformación compatible y escribir una nueva versión Delta o crear un alias/view para la versión vigente.

Paso 2: Definir esquemas en JSON

Crea archivos JSON con la definición del esquema esperado. Mantén cada versión clara (v1, v2...). Esto permite comparar programáticamente.

# exemplo de schema v1 (schema_v1.json)
{
  "fields": [
    {"name": "id", "type": "long", "nullable": false},
    {"name": "nome", "type": "string", "nullable": true},
    {"name": "valor", "type": "double", "nullable": true}
  ]
}

# exemplo de schema v2 (schema_v2.json) adiciona coluna 'categoria'
{
  "fields": [
    {"name": "id", "type": "long", "nullable": false},
    {"name": "nome", "type": "string", "nullable": true},
    {"name": "valor", "type": "double", "nullable": true},
    {"name": "categoria", "type": "string", "nullable": true}
  ]
}

Paso 3: Cargar datos de ingestión e inferir esquema

Carga el archivo de entrada y transforma los tipos; compara con el esquema esperado usando PySpark. Si es necesario, aplica coerción de tipos o añade columnas faltantes con valores nulos/por defecto.

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType
import json

spark = SparkSession.builder.getOrCreate()

# caminho para o CSV de ingestão
input_path = '/mnt/lakehouse/raw/ingest/input.csv'

df = spark.read.option('header', 'true').csv(input_path)

# carregar esquema esperado (v2) do JSON
with open('/dbfs/mnt/lakehouse/schemas/schema_v2.json') as f:
    schema_json = json.load(f)
    # converter para StructType simples: exemplo mínimo
    expected_fields = [(f['name'], f['type']) for f in schema_json['fields']]

# função simples de coerção/ajuste
for name, typ in expected_fields:
    if name not in df.columns:
        df = df.withColumn(name, spark.sql.functions.lit(None).cast('string'))

# coerção de tipo mínima (exemplo): cast para double quando requerido
if 'valor' in df.columns:
    df = df.withColumn('valor', df['valor'].cast('double'))

Paso 4: Validar y registrar incompatibilidades

Valida si existen columnas extra, tipos incompatibles o claves primarias ausentes. Registra problemas en un archivo de auditoría para permitir fallback.

# detectar colunas extra
expected_names = [f[0] for f in expected_fields]
extra = [c for c in df.columns if c not in expected_names]

# exemplo de registo simples
audit = {
  'input_path': input_path,
  'expected_schema': expected_names,
  'found_columns': df.columns,
  'extra_columns': extra
}

# grava audit como JSON numa pasta de governação
import json
with open('/dbfs/mnt/lakehouse/audit/schema_audit.json', 'w') as f:
    f.write(json.dumps(audit))

Paso 5: Aplicar transformación compatible y escribir como tabla Delta

Tras el ajuste, escribe los datos en una tabla Delta con la versión del esquema en los metadatos (por ejemplo, tabla nome_versionada_v2). Mantén tablas por versión o actualiza una view/alias.

target_path = '/mnt/lakehouse/curated/minha_tabela_v2'

# escrever Delta
(df
 .write
 .format('delta')
 .mode('append')
 .save(target_path))

# criar/atualizar uma tabela gerida ou external table (SQL)
spark.sql(f"CREATE TABLE IF NOT EXISTS minha_tabela_v2 USING DELTA LOCATION '{target_path}'")

# opcional: atualizar uma view 'minha_tabela' para apontar para a versão corrente
spark.sql("CREATE OR REPLACE VIEW minha_tabela AS SELECT * FROM minha_tabela_v2")

Paso 6: Fallback y rollback de esquema

Si una versión nueva falla validaciones aguas arriba o aguas abajo, usa la auditoría y el historial Delta para revertir: puedes apuntar la view a la versión anterior o restaurar la tabla a un snapshot conocido usando Time Travel.

# exemplo de rollback com time travel (se necessário)
spark.sql("CREATE OR REPLACE VIEW minha_tabela AS SELECT * FROM minha_tabela_v1")

# ou restaurar Delta para um commit anterior via RESTORE/Time Travel (exemplo SQL)
-- RESTORE não é universal; use Time Travel: SELECT * FROM delta.`/path` VERSION AS OF X

Verificar el resultado

Confirma que la tabla/view apunta a la versión correcta y que los consumidores pueden leer los datos sin errores. Verifica el archivo de auditoría e inspecciona tipos/columnas con DESCRIBE TABLE o spark.printSchema().

# verificar esquema
spark.table('minha_tabela').printSchema()

# ver audit
with open('/dbfs/mnt/lakehouse/audit/schema_audit.json') as f:
    print(f.read())

Conclusión

Versionar esquemas en Lakehouse reduce fallos y facilita evoluciones controladas: se mantienen archivos JSON de esquema, se valida la ingestión, se aplican coerciones y se registra auditoría. Próximos pasos: automatizar con un job/orquestador, añadir pruebas de regresión de esquema e integrar con CI/CD. Consejo: empieza por crear un pequeño conjunto de reglas de validación para evitar sorpresas en producción.