¿Cuántos datos están siendo almacenados en mi OneLake?
Autor
Kilian Baccaro Salinas
Categoría
Lakehouse
Tiempo de lectura
04 min de lectura
Fecha de publicación
12 may, 2025
Si estás metido en el mundo de Microsoft Fabric, seguro que ya conoces OneLake. Piensa en él como el “OneDrive de tus datos”: un sitio único y para todos donde guardar la información de la empresa. Suena genial, ¿verdad? Centralizarlo todo facilita un montón la vida para organizar, compartir y no tener datos repetidos por todas partes. Pero claro, a medida que metes más y más proyectos y datos, te empiezas a preguntar: ¿Cuánto espacio estoy usando realmente y qué es lo que más pesa?
Y ojo, que responder a eso tiene su miga. Con un montón de workspaces, cada uno con sus cosas (Lakehouses, Warehouses, Modelos Semánticos, Bases de Datos KQL…), saber exactamente qué ocupa cada cosa es un pequeño lío.
Para abordar este desafío, he desarrollado un notebook de PySpark dentro de Microsoft Fabric que nos permite automatizar este proceso, ofreciendo una visión detallada del uso del almacenamiento en OneLake.
El desafío: Ver claro entre tanta cosa
OneLake es la casa de muchos tipos de artefactos de Fabric. Algunos, como las Lakehouses, son como carpetas y archivos que puedes ver y tocar fácilmente. Pero otros, como los Modelos Semánticos o los Warehouses, son un poco más “caja negra”; su tamaño no es solo sumar archivos, sino que Fabric los maneja a su manera.
Ir mirando esto a mano, workspace por workspace, es una locura, y más si tu empresa tiene unos cuantos.
La solución: Un notebook de PySpark al rescate
El notebook aprovecha el poder de PySpark en el entorno de Microsoft Fabric y las capacidades de la librería sempy para interactuar programáticamente con los workspaces y artefactos. El proceso general que sigue el notebook es el siguiente:
-
Listar Workspaces: Utiliza
sempy.fabric.list_workspaces()para obtener una lista de todos los workspaces a los que el usuario tiene acceso. -
Listar artefactos por workspace: Para cada workspace, emplea
sempy.fabric.list_items()para inventariar todos los artefactos. -
Determinar el tipo de artefacto: Identifica el tipo de cada artefacto (
Lakehouse,Warehouse,SemanticModel,KQLDatabase, etc.). -
Calcular el tamaño:
-
Modelos Semánticos: Intenta obtener el tamaño utilizando la función
sempy_labs.get_semantic_model_size(). Es importante destacar que el usuario debe disponer de permisos para ejecutar esta función. Si esta función falla o no devuelve un tamaño, se registra un marcador. -

-
Artefactos basados en archivos (Lakehouse, Warehouse, etc.): Para artefactos cuyo almacenamiento es directamente accesible como archivos y carpetas en OneLake (a través de rutas ABFSS), el notebook implementa una función recursiva (
get_file_details_recursive). Esta función utilizanotebookutils.fs.ls()para navegar por la estructura de directorios del artefacto y sumar el tamaño de cada archivo individual. -
Otros tipos de artefactos: Para tipos de artefactos donde el tamaño no se obtiene directamente de los archivos ABFSS (por ejemplo,
Report,Notebook,DataPipeline), el script actualmente los omite o permite añadir un marcador de tamaño cero, ya que su “tamaño” en OneLake suele ser despreciable en comparación con los artefactos de datos.
-
-
Almacenar en una tabla delta: Finalmente, el DataFrame se guarda en una tabla Delta dentro de un Lakehouse.
import sempy_labs as labs
import sempy.fabric as fabric
import pandas as pd
from pyspark.sql.types import *
from pyspark.sql.functions import col
def get_file_details_recursive(folder_path):
file_details_list = []
try:
items = notebookutils.fs.ls(folder_path)
for item in items:
item_path_full = item.path
if not item_path_full.startswith("abfss://"):
if folder_path.endswith('/'):
item_path_full = folder_path + item.name
else:
item_path_full = folder_path + '/' + item.name
if not item.isDir:
file_details_list.append({'path': item_path_full, 'size_bytes': item.size})
else:
current_folder_normalized = folder_path.rstrip('/')
item_folder_normalized = item_path_full.rstrip('/')
if item_folder_normalized != current_folder_normalized:
sub_dir_files = get_file_details_recursive(item_path_full)
if sub_dir_files:
file_details_list.extend(sub_dir_files)
except Exception as e:
print(f"WARN: Error al escanear la carpeta '{folder_path}'. Omitiendo esta ruta.")
return []
return file_details_list
all_files_data = []
processed_workspaces = 0
total_workspaces = 0
print("Iniciando escaneo de workspaces...")
try:
workspaces_pd = fabric.list_workspaces()
total_workspaces = len(workspaces_pd)
print(f"Se encontraron {total_workspaces} áreas de trabajo accesibles.")
for ws_index, ws_row in workspaces_pd.iterrows():
workspace_name = ws_row['Name']
workspace_id = ws_row['Id']
processed_workspaces += 1
print(f"\n[{processed_workspaces}/{total_workspaces}] 📂 Procesando Workspace: '{workspace_name}' (ID: {workspace_id})")
try:
items_pd = fabric.list_items(workspace=workspace_id)
print(f" -> Se encontraron {len(items_pd)} artefactos escaneables en '{workspace_name}'.")
for item_index, item_row in items_pd.iterrows():
artifact_type = item_row['Type']
artifact_name = item_row['Display Name']
artifact_id = item_row['Id']
artifact_root_path = f"abfss://{workspace_id}@onelake.dfs.fabric.microsoft.com/{artifact_id}"
print(f" -> 🔍 Escaneando artefacto: '{artifact_name}' (Tipo: {artifact_type}, ID: {artifact_id})")
files_in_artifact = []
special_size_bytes = -1
try:
if artifact_type == 'SemanticModel':
print(f" -> Intentando obtener tamaño para Semantic Model '{artifact_name}'...")
size = labs.get_semantic_model_size(artifact_id, workspace_id)
if size is not None:
special_size_bytes = int(size)
print(f" => Tamaño obtenido de sempy_labs: {special_size_bytes} bytes.")
all_files_data.append({
"WorkspaceID": workspace_id,
"WorkspaceName": workspace_name,
"ArtifactType": artifact_type,
"ArtifactName": artifact_name,
"ArtifactID": artifact_id,
"ScannedRootPath": artifact_root_path,
"FilePath": f"{artifact_root_path}",
"SizeBytes": special_size_bytes,
"SizeMB": float(special_size_bytes / (1024 * 1024)) if special_size_bytes > 0 else 0.0
})
else:
files_in_artifact = get_file_details_recursive(artifact_root_path + "/")
if files_in_artifact and artifact_type != 'SemanticModel':
print(f" => Se encontraron {len(files_in_artifact)} archivos para '{artifact_name}'.")
for file_detail in files_in_artifact:
file_size_bytes = int(file_detail['size_bytes'])
file_size_mb = float(file_size_bytes / (1024 * 1024)) if file_size_bytes > 0 else 0.0
all_files_data.append({
"WorkspaceID": workspace_id,
"WorkspaceName": workspace_name,
"ArtifactType": artifact_type,
"ArtifactName": artifact_name,
"ArtifactID": artifact_id,
"ScannedRootPath": artifact_root_path,
"FilePath": file_detail['path'],
"SizeBytes": file_size_bytes,
"SizeMB": file_size_mb
})
else:
print(f" => No se encontraron archivos accesibles vía ABFSS para '{artifact_name}' o está vacío.")
except Exception as scan_error:
print(f" => ERROR escaneando el artefacto '{artifact_name}' en '{artifact_root_path}'.")
all_files_data.append({
"WorkspaceID": workspace_id,
"WorkspaceName": workspace_name,
"ArtifactType": artifact_type,
"ArtifactName": artifact_name,
"ArtifactID": artifact_id,
"ScannedRootPath": artifact_root_path,
"FilePath": "ERROR_SCANNING_ARTIFACT",
"SizeBytes": -1,
"SizeMB": -1.0
})
except Exception as item_error:
print(f" -> ERROR al listar artefactos para el workspace '{workspace_name}': {item_error}")
continue
except Exception as ws_error:
print(f"FATAL: Error crítico al obtener la lista de workspaces: {ws_error}")
print(f"\n📊 Escaneo completado. Se recopilaron {len(all_files_data)} registros de archivos.")




Notebook completo: GitHub
Beneficios
Esta tabla es un recurso valioso para:
-
Gobernanza del almacenamiento: Identificar qué workspaces, artefactos o incluso qué rutas específicas dentro de un Lakehouse están consumiendo más espacio.
-
Mantenimiento y limpieza: Detectar datos obsoletos, innecesariamente grandes o duplicados que podrían ser archivados o eliminados.
-
Informes y dashboards: Conectar Power BI directamente a esta tabla Delta para crear visualizaciones interactivas del uso del almacenamiento.
-
Automatización: Al ser un notebook, puede programarse su ejecución periódica para tener un seguimiento continuo del crecimiento del almacenamiento.
Consideraciones y Limitaciones
-
La función
get_semantic_model_sizepuede no devolver el tamaño si el usuario no tiene los permisos suficientes. -
Tamaño lógico vs. físico: Para artefactos como Modelos Semánticos en modo Direct Lake o Warehouses, la suma de los tamaños de los archivos Delta subyacentes accesibles vía ABFSS puede no coincidir exactamente con el tamaño lógico que Fabric gestiona internamente o reporta en otras interfaces.
-
Permisos: La identidad que ejecuta el notebook necesita los permisos adecuados para listar workspaces, ítems dentro de esos workspaces y acceder a las rutas ABFSS de los artefactos.
-
Rendimiento: En entornos con una cantidad masiva de workspaces, artefactos y archivos, la ejecución del notebook podría llevar un tiempo considerable.
Referencias
NotebookUtils (former MSSparkUtils) for Fabric - Microsoft Fabric | Microsoft Learn