Análisis del precio de las criptomonedas en tiempo real con Microsoft Fabric – Parte 2: Transformación y preparación analítica de datos

Autor

Kilian Baccaro Salinas

Categoría

Real-Time Intelligence

Tiempo de lectura

02 min de lectura

Fecha de publicación

24 oct, 2025

Objetivo

En esta fase abordaremos la transformación, limpieza y preparación analítica de los datos obtenidos en la capa Bronze. El propósito es construir las capas Silver y Gold dentro de nuestra arquitectura Medallion, garantizando datos consistentes, enriquecidos y optimizados para el análisis.

Capa Silver — Transformación y enriquecimiento de datos

La capa Silver representa el siguiente paso tras la ingestión de datos crudos en la base de datos KQL. Su objetivo es transformar, limpiar, enriquecer y estructurar los datos provenientes de la capa RAW para que estén listos para análisis más complejos o visualizaciones.

En esta etapa se aplican transformaciones como:

  • Conversión de formatos de fecha/hora.

  • Extracción de campos anidados (por ejemplo, desde JSON).

  • Tipado correcto de columnas (por ejemplo, price como real).

  • Enriquecimiento de datos con campos adicionales.

  • Eliminación de duplicados.

Gracias a las Update Policies, estas transformaciones se ejecutan de forma automática y en tiempo real, cada vez que nuevos datos se insertan en la tabla RAW.

Transformaciones en tiempo real con Update Policies

Para poder lanzar consultas KQL, utilizaremos un nuevo artefacto llamado KQL Queryset.

1. Crear la tabla destino (Crypto_Silver)

.create table Crypto_Silver (
    serverTime: datetime,
    symbol: string,
    price: real
) 
with (folder = "Silver")

2. Crear una función de transformación

Esta función convierte el serverTime desde milisegundos Unix a datetime, analiza el campo JSON tickerInfo y extrae el symbol y el price como columnas limpias.

.create-or-alter function LoadCryptoToSilver {
    Crypto_RAW
    | extend serverTime = unixtime_milliseconds_todatetime(serverTime), j = parse_json(tickerInfo)
    | extend symbol = tostring(j.symbol), price = toreal(j.price)
    | project serverTime, symbol, price
}

3. Crear y activar la Update Policy

.alter table Crypto_Silver policy update 
```[
    {
        "IsEnabled": true,
        "Source": "Crypto_RAW",
        "Query": "LoadCryptoToSilver",
        "IsTransactional": true,
        "PropagateIngestionProperties": false
    }
]```

Con esta configuración, cualquier nuevo dato que entre en Crypto_RAW activará automáticamente la función y los resultados se escribirán en Crypto_Silver.


Capa Gold — Agregación y preparación analítica

La capa Gold representa la última fase de nuestra arquitectura Medallion. En nuestro proyecto, seguimos un doble enfoque:

  1. Vista materializada → para obtener de forma optimizada el último valor de cada criptomoneda.

  2. Función KQL → para consultar el histórico y analizar la evolución de precios.

Vista materializada: Último valor por criptomoneda

.create-or-alter materialized-view with (backfill = true) mvCryptoGoldLatest on table Crypto_Silver
{
    Crypto_Silver
    | where price > 0
    | summarize arg_max(serverTime, *) by symbol
}
  • backfill=true: rellena la vista con los datos históricos existentes.

  • arg_max(serverTime, *): selecciona el registro con la fecha más reciente para cada símbolo.

Función: Histórico filtrado

.create-or-alter function with(view=true) vwCrypto()
{
    Crypto_Silver
    | where price > 0
}

Consultando los datos en tiempo real

En la capa Gold, disponemos de tres formas principales de acceder a los datos:

Consultar la vista materializada

mvCryptoGoldLatest

Esta consulta combina la parte materializada con los registros recientes aún no materializados (.delta).

También puedes usar la función materialized_view() para consultar únicamente la parte ya materializada:

materialized_view('mvCryptoGoldLatest')

Consultar el histórico con la vista normal

vwCrypto

También puedes encadenar transformaciones sobre la vista:

vwCrypto()
| where symbol == "BTCEUR"
| summarize avgPrice = avg(price) by bin(serverTime, 1h)