En una entrada anterior vimos cómo crear paso a paso un Data Lake en Azure, configurando los permisos y contenedores necesarios. En esta ocasión, vamos a dar el siguiente paso natural: cargar datos desde Python a Azure Data Lake Storage Gen2, utilizando las librerías oficiales de Microsoft.
El objetivo de este tutorial es mostrar cómo un servicio o script en Python puede enviar datos automáticamente al Data Lake, ya sea información generada por un proceso ETL, resultados de un modelo de Machine Learning o registros recogidos en tiempo real desde una API.
Este enfoque es muy útil cuando:
- Tienes pipelines de datos escritos en Python que generan resultados o transformaciones intermedias.
- Deseas automatizar la ingesta de datos sin depender del portal de Azure o herramientas de escritorio.
- Quieres integrar tu Data Lake dentro de un flujo de análisis o machine learning reproducible.
A lo largo de esta guía veremos:
- Cómo preparar el entorno e instalar las dependencias necesarias.
- Cómo configurar las credenciales para conectar con tu cuenta de almacenamiento de Azure.
- Cómo generar datos sintéticos (CSV y Parquet) usando
pandasyfaker. - Cómo subir esos datos al contenedor raw de tu Data Lake y verificar que la carga se realizó correctamente.
Al finalizar, tendrás un script funcional en Python capaz de enviar datos al Data Lake de Azure de forma segura y automatizada.

Tabla de contenidos
- 1 Preparación del entorno
- 2 Configuración de las credenciales
- 3 Conexión al contenedor
- 4 Generar datos sintéticos con Faker y Pandas
- 5 Subir el DataFrame como CSV al Data Lake
- 6 Verificar los blobs existentes en el contenedor
- 7 Leer el archivo desde Azure (verificación de la carga)
- 8 Verificar la integridad del archivo con Checksum
- 9 Conclusiones
Preparación del entorno
Para cargar datos desde Python a Azure Data Lake vamos a utilizar cuatro paquetes principales:
- azure-storage-blob: Conectarse y gestionar archivos en Azure Blob Storage o Data Lake Storage Gen2.
- pandas: Manipulación y exportación de datos tabulares.
- pyarrow: Soporte para el formato Parquet, ideal para almacenar datos analíticos.
- faker: Generación de datos falsos o sintéticos (nombres, fechas, emails, etc.) para pruebas.
Para instalar los paquetes, simplemente ejecuta el siguiente comando en la terminal o PowerShell:
pip install azure-storage-blob pandas pyarrow faker
Configuración de las credenciales
Para poder conectarte a tu Azure Data Lake Storage Gen2, necesitas autenticarte ante el servicio. La forma más sencilla para es usar la Connection String, que puedes obtener desde el portal de Azure:
- Ve al Azure Portal.
- Abre tu Storage Account (la cuenta que contiene tu Data Lake).
- En el menú lateral, selecciona Access keys.
- Copia la Connection string (por ejemplo, algo como
DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net).
Importante: Nunca incluyas esta cadena directamente en tu código fuente ni la subas a un repositorio. En su lugar, guárdala como una variable de entorno del sistema.
En Windows
Puedes definir la variable de entorno desde PowerShell:
setx AZURE_STORAGE_CONNECTION_STRING "DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"
Después de ejecutar el comando, reinicia tu terminal o tu editor (VS Code, por ejemplo) para que la variable esté disponible.
Puedes verificar que se ha guardado correctamente con:
echo $env:AZURE_STORAGE_CONNECTION_STRING
En Linux
En distribuciones como Ubuntu o Debian, puedes establecer la variable de entorno temporalmente en el terminal actual:
export AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"
Si quieres que se cargue automáticamente cada vez que inicies sesión, añádela al archivo ~/.bashrc o ~/.zshrc:
echo 'export AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"' >> ~/.bashrc source ~/.bashrc
Para comprobarla:
echo $AZURE_STORAGE_CONNECTION_STRING
En macOS
El proceso es muy similar al de Linux. Si usas zsh (el shell por defecto en macOS):
export AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"
Para hacerla persistente:
echo 'export AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net"' >> ~/.zshrc source ~/.zshrc
Puedes verificar que la variable está disponible con:
echo $AZURE_STORAGE_CONNECTION_STRING
Verificar de la configuración de las credenciales en Python
Antes de continuar, es importante comprobar que los sciprts de Python puede acceder a la variable de entorno con las cadena de conexión:
import os
conn_str = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
if conn_str:
print("Conexión con Azure configurada correctamente.")
else:
print("No se encontró la variable de entorno AZURE_STORAGE_CONNECTION_STRING.")Si todo es correcto, se debería ver el mensaje: ”Conexión con Azure configurada correctamente.” Si no es así, es necesario revisar los pasos anteriores antes de continuar.
Conexión al contenedor
Una vez configurada la cadena de conexión al Data Lake, el siguiente paso es establecer la conexión con el servicio de almacenamiento y acceder al contenedor donde guardaremos los datos. En este ejemplo, utilizaremos un contenedor llamado raw, que normalmente corresponde a la capa donde se almacenan los datos en bruto antes de ser procesados.
Para realizar la conexión usaremos la clase BlobServiceClient del paquete azure-storage-blob. Esta clase permite interactuar con el servicio de Azure Blob Storage (o Data Lake Storage Gen2) de forma sencilla, creando contenedores, subiendo archivos o listando su contenido.
El siguiente fragmento de código muestra cómo conectar al servicio, obtener el cliente del contenedor y crearlo si no existe:
from azure.storage.blob import BlobServiceClient
# Leer la cadena de conexión
connect_str = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
# Crear cliente de servicio
blob_service_client = BlobServiceClient.from_connection_string(connect_str)
# Nombre del contenedor
container_name = "raw"
container_client = blob_service_client.get_container_client(container_name)
# Crear el contenedor si no existe
try:
container_client.create_container()
print(f"Contenedor '{container_name}' creado correctamente.")
except Exception:
print(f"El contenedor '{container_name}' ya existe.")Si todo se ejecuta correctamente, verás un mensaje indicando que el contenedor fue creado o que ya existía previamente.
Consejo: Este bloque de código suele usarse solo la primera vez que se inicializa el Data Lake o durante la configuración del entorno. En un entorno de producción o dentro de un pipeline automatizado, normalmente se asume que el contenedor de destino ya existe, y solo se establece la conexión para subir archivos o leer datos.
Generar datos sintéticos con Faker y Pandas
Ahora que ya tenemos configurada la conexión con nuestro Data Lake, el siguiente paso es disponer de un conjunto de datos que podamos cargar para realizar pruebas. En lugar de usar archivos reales, podemos generar datos sintéticos fácilmente con ayuda de las librerías Faker y Pandas.
El paquete Faker permite crear datos ficticios realistas (nombres, direcciones, fechas, correos electrónicos, etc.) en diferentes idiomas o culturas, lo que resulta ideal para pruebas de integración o desarrollo. Por su parte, Pandas nos servirá para estructurar esos datos en forma tabular y exportarlos luego en los formatos deseados.
En este ejemplo, vamos a generar 100.000 registros aleatorios que simulan las ventas de una tienda de informática. Cada registro incluirá información sobre la fecha de la venta, el producto, las unidades vendidas, el precio unitario, el total, el vendedor y la ciudad.
import pandas as pd
import random
from faker import Faker
from datetime import datetime, timedelta
# Configurar la localización de Faker
fake = Faker("es_ES")
# Definir el número de registros
n = 100_000
data = []
for _ in range(n):
fecha = fake.date_between(start_date='-30d', end_date='today')
producto = random.choice(["Laptop", "Smartphone", "Tablet", "Monitor", "Teclado", "Ratón"])
unidades = random.randint(1, 10)
precio_unitario = round(random.uniform(50, 1500), 2)
total = round(unidades * precio_unitario, 2)
vendedor = fake.name()
ciudad = fake.city()
data.append([fecha, producto, unidades, precio_unitario, total, vendedor, ciudad])
df = pd.DataFrame(data, columns=["fecha", "producto", "unidades", "precio_unitario", "total", "vendedor", "ciudad"])
df.head()fecha producto unidades precio_unitario total \
0 2025-11-05 Smartphone 9 189.39 1704.51
1 2025-11-22 Ratón 3 191.08 573.24
2 2025-11-30 Smartphone 10 1058.26 10582.60
3 2025-11-11 Ratón 4 1446.66 5786.64
4 2025-11-20 Ratón 4 1412.68 5650.72
vendedor ciudad
0 Alejo Amo Arteaga Ciudad
1 Constanza Corominas Pozuelo Pontevedra
2 Ramona Soto-Sáez Cuenca
3 Eduardo del Ferrer Ceuta
4 Rómulo Alarcón-Llabrés Tarragona
Al ejecutar este código, se generará un DataFrame de Pandas con 100.000 registros simulando ventas.
Consejo: La librería Faker incluye localizaciones para muchos idiomas (en_US, fr_FR, es_MX, etc.). Cambiar la localización permite que los nombres y ciudades de España sean más próximos a los esperados.
Subir el DataFrame como CSV al Data Lake
Ya disponemos de un DataFrame con datos simulados, así que el siguiente paso consiste en subirlo al Data Lake. No es necesario guardar el archivo temporalmente en disco; podemos escribirlo directamente en memoria y enviarlo al contenedor de Azure.
Para ello, utilizaremos un BytesIO como buffer intermedio, y construiremos un nombre de archivo organizado por año y mes (útil para estructurar el Data Lake siguiendo buenas prácticas de particionado temporal).
from io import BytesIO
from datetime import date
# Convertir el DataFrame a CSV en memoria
buffer = BytesIO()
df.to_csv(buffer, index=False)
buffer.seek(0)
# Crear nombre lógico del archivo con ruta año/mes automática
today = date.today()
year = today.strftime("%Y")
month = today.strftime("%m")
blob_name = f"{year}/{month}/ventas_demo_{today}.csv"
# Subir el CSV al contenedor RAW
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
blob_client.upload_blob(buffer, overwrite=True)
print(f"Archivo CSV '{blob_name}' subido correctamente al contenedor '{container_name}'.")Este código genera automáticamente una carpeta por año y mes dentro del contenedor (raw/2025/11/), lo que facilita la organización y posterior procesamiento de los datos en pipelines o herramientas como Azure Synapse, Databricks o Data Factory.
Subir el mismo DataFrame en formato Parquet
El formato Parquet es ampliamente utilizado en entornos de Big Data porque almacena la información en forma columnar, lo que reduce significativamente el tamaño de los archivos y mejora el rendimiento en operaciones analíticas.
Subir un archivo Parquet al Data Lake es tan sencillo como cambiar el método to_csv() por to_parquet():
# Convertir el DataFrame a Parquet en memoria
buffer = BytesIO()
df.to_parquet(buffer, index=False)
buffer.seek(0)
# Generar nombre lógico con la misma estructura temporal
blob_name_parquet = f"{year}/{month}/ventas_demo_{today}.parquet"
# Subir el archivo Parquet
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name_parquet)
blob_client.upload_blob(buffer, overwrite=True)
print(f"Archivo Parquet '{blob_name_parquet}' subido correctamente al contenedor '{container_name}'.")De esta manera, tendrás en tu Data Lake los mismos datos disponibles en dos formatos:
- CSV, más universal y fácil de inspeccionar.
- Parquet, más eficiente para análisis y almacenamiento a gran escala.
Esta práctica es especialmente útil en entornos de Data Engineering, donde distintos sistemas pueden requerir formatos diferentes según el tipo de procesamiento o herramienta utilizada.
Verificar los blobs existentes en el contenedor
Una vez subidos los archivos, es una buena práctica verificar que ambos se encuentran correctamente almacenados en el contenedor del Data Lake. Esto también nos permitirá comparar el tamaño entre los formatos CSV y Parquet, lo que suele reflejar claramente la ventaja del formato columnar en términos de espacio.
Podemos listar todos los blobs del contenedor raw con el siguiente código:
print("Archivos disponibles en el contenedor:")
for blob in container_client.list_blobs():
if blob.size == 0:
print(f" - {blob.name}")
else:
size_mb = blob.size / (1024 * 1024) # Convertir bytes a MB
print(f" - {blob.name} ({size_mb:.2f} MB)")Esto mostrará una salida similar a la siguiente:
Archivos disponibles en el contenedor:
- 2025
- 2025/11
- 2025/11/ventas_demo_2025-11-22.csv (6.39 MB)
- 2025/11/ventas_demo_2025-11-22.parquet (2.96 MB)
Como se puede observar, el archivo Parquet ocupa mucho menos espacio que el CSV, incluso cuando contienen exactamente los mismos datos. Esta diferencia es una de las principales razones por las que Parquet se ha convertido en el formato estándar para almacenamiento analítico en entornos de Big Data y Data Lakes modernos.
Consejo: En proyectos reales, este tipo de comprobación puede automatizarse dentro de un pipeline de carga o en scripts de validación, garantizando que los archivos se suben correctamente y cumplen con las políticas de particionado y almacenamiento.
Leer el archivo desde Azure (verificación de la carga)
Una vez que los archivos se han subido correctamente al Data Lake, es buena práctica comprobar que pueden leerse sin errores. De este modo confirmamos que el proceso de escritura y la configuración de acceso funcionan correctamente.
Podemos hacerlo fácilmente leyendo el mismo archivo que acabamos de subir:
# Leer el archivo CSV de vuelta desde Azure blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name) # Descargar el contenido del blob a un buffer en memoria stream = BytesIO() data = blob_client.download_blob() stream.write(data.readall()) stream.seek(0) # Cargarlo como DataFrame de pandas df_verificado = pd.read_csv(stream) df_verificado.head()
fecha producto unidades precio_unitario total \
0 2025-11-05 Smartphone 9 189.39 1704.51
1 2025-11-22 Ratón 3 191.08 573.24
2 2025-11-30 Smartphone 10 1058.26 10582.60
3 2025-11-11 Ratón 4 1446.66 5786.64
4 2025-11-20 Ratón 4 1412.68 5650.72
vendedor ciudad
0 Alejo Amo Arteaga Ciudad
1 Constanza Corominas Pozuelo Pontevedra
2 Ramona Soto-Sáez Cuenca
3 Eduardo del Ferrer Ceuta
4 Rómulo Alarcón-Llabrés Tarragona
Si todo ha ido bien, deberías ver en pantalla las primeras filas del DataFrame original, lo que confirma que la carga al Data Lake fue exitosa
Nota: Este tipo de verificación es útil en entornos de desarrollo o pruebas, pero no se recomienda hacerlo en producción. En sistemas reales, la comprobación de integridad debería realizarse mediante checksums, logs de control o procesos de auditoría de datos, no descargando los archivos completos.
Verificar la integridad del archivo con Checksum
En entornos de producción no es recomendable descargar los archivos para comprobar si se han cargado correctamente. Una alternativa más eficiente y segura es verificar su integridad comparando un hash o checksum calculado localmente antes de subirlo con el hash del archivo almacenado en Azure.
Esto permite asegurarse de que el archivo no se ha corrompido durante la transferencia.
Calcular el hash local antes de subir el archivo
Inicialmente, podemos generar un hash MD5 o SHA256 del contenido del archivo directamente desde el buffer antes de subirlo. Por ejemplo, usando hashlib:
import hashlib
# Calcular el hash del CSV antes de subirlo
buffer.seek(0)
hash_local = hashlib.md5(buffer.read()).hexdigest()
print("Hash local:", hash_local)
# Volvemos el buffer al inicio antes de subirlo
buffer.seek(0)
# Subir el blob (como antes)
blob_client.upload_blob(buffer, overwrite=True)Hash local: a2711dd21fce6a7b3baa666cf0b7913e
Recuperar el hash del blob en Azure
Azure Blob Storage genera automáticamente un MD5 hash de cada blob subido, disponible en sus propiedades. Podemos acceder a él fácilmente:
# Obtener propiedades del blob
props = blob_client.get_blob_properties()
# Azure almacena el MD5 en formato base64
import base64
hash_azure = base64.b64encode(props.content_settings.content_md5).decode()
print("Hash en Azure (base64):", hash_azure)Hash en Azure (base64): onEd0h/Oans7qmZs8LeRPg==
Comparar ambos hashes
El único problema, es que en Azure el hash se tiene en base 64, así que para solo hay que transformar la base para comparar los hashes. Para verificar la integridad se puede hacer con:
# Convertir el hash local a base64 para compararlo
hash_local_base64 = base64.b64encode(bytes.fromhex(hash_local)).decode()
if hash_local_base64 == hash_azure:
print("El archivo se ha cargado correctamente (hash coincidente).")
else:
print("El archivo podría haberse modificado o corrompido durante la carga.")El archivo se ha cargado correctamente (hash coincidente).
Consejo: Usar checksums es una práctica recomendada en pipelines de datos críticos, ya que permite detectar errores silenciosos durante la carga o transferencia de grandes volúmenes de información.
Conclusiones
En este tutorial hemos recorrido todos los pasos necesarios para cargar datos desde Python a un Data Lake en Azure de forma segura y automatizada.
Entre los puntos más importantes que hemos visto se incluyen:
- Preparación del entorno: instalación de librerías clave como
azure-storage-blob,pandas,pyarrowyfakerpara generar y manejar datos de prueba. - Configuración de credenciales: uso de la Connection String guardada en variables de entorno, evitando almacenar información sensible directamente en el código.
- Generación de datos sintéticos: creación de un DataFrame con información ficticia para simular ventas, usando
Fakerypandas. - Carga de archivos al Data Lake: subida de los datos en formatos CSV y Parquet, utilizando buffers en memoria, y organizando los blobs automáticamente por año y mes para mantener una estructura escalable.
- Verificación de la carga: lectura de archivos desde Azure y comparación de los datos, así como la comprobación de integridad mediante checksums para garantizar que los archivos no se corrompen durante la transferencia.
- Buenas prácticas implícitas: uso de contenedores jerárquicos (
raw), nombres de archivos coherentes, separación por formatos y particionamiento temporal, todo pensado para facilitar pipelines futuros y analítica eficiente.
Con estos pasos y buenas prácticas, tu Data Lake en Azure estará listo para recibir datos de cualquier origen y servir como base sólida para análisis, visualización o modelos de Machine Learning.
Nota: La imagen de este artículo fue generada utilizando un modelo de inteligencia artificial.
Deja una respuesta