CAPÍTULO 6 · Los datos empiezan a llegar
Lo que sale de la plataforma también lleva nuestras decisiones
Una exportación parece una función sencilla hasta que preguntamos qué debe incluir. El usuario espera que el archivo corresponda al período, los filtros y los permisos con los que estaba trabajando. Si generamos el reporte desde otra consulta sin esos límites, la descarga puede contar una historia distinta de la pantalla o revelar información adicional.
Definimos columnas, formatos, unidades y alcance para la exportación. El contrato del archivo se vuelve parte del producto, porque alguien lo interpretará fuera de nuestra interfaz. También consideramos el volumen: un conjunto grande puede necesitar un proceso diferente al de devolver una página de una tabla.
Ahora SensorHub puede convertir sus datos en un resultado transportable. En algunos casos ese resultado o un evento debe llegar a una persona sin que esta vuelva a abrir la plataforma. Ya estudiamos cómo separar efectos externos; el correo ofrece una oportunidad concreta para aplicar esa decisión y comprobar sus consecuencias.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
MIRA · CONECTA · COMPRENDE
Una salida con un contrato seguro
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Solicitante. Define reporte requerido
- Alcance. Restringe datos autorizados
- Consulta. Obtiene valores exportables
- CSV / reporte. Entrega formato controlado
01 / EL PROBLEMA
¿Para qué sirve?
El CSV y el PDF deben representar las mismas unidades y contexto que el resto de la aplicación. La descarga también es un endpoint.
02 / COMPRENDER
El concepto, explicado
Streaming evita construir un archivo completo en memoria cuando la fuente también se itera incrementalmente. No elimina automáticamente el costo de la consulta.
Un reporte debe declarar rango, timezone, unidades, configuración y resultado. Aplícale el mismo alcance de acceso que a la consulta.
03 / CONSTRUIR
Implementación paso a paso
- Autoriza y valida rango.
- Selecciona columnas explícitas.
- Itera sin cargar todo en memoria.
- Usa nombres y content types apropiados.
04 / APLICAR
Ejemplo en SensorHub
import csv
from django.http import StreamingHttpResponse
class Echo:
def write(self, value):
return value
def export_rows(queryset):
writer = csv.writer(Echo())
yield writer.writerow(["fecha_utc", "temperatura_c"])
for row in queryset.iterator(chunk_size=1000):
yield writer.writerow([row.occurred_at.isoformat(), row.value])
response = StreamingHttpResponse(
export_rows(authorized_queryset), content_type="text/csv; charset=utf-8"
)
response["Content-Disposition"] = 'attachment; filename="temperaturas.csv"'Cómo leer el ejemplo
- Echo permite que csv.writer retorne cada fila como texto.
- authorized_queryset debe delimitar sensor y permisos antes de exportar.
- El esquema de columnas identifica unidades explícitamente.
Error habitual
Textos de usuarios que empiezan con =, +, - o @ pueden interpretarse como fórmulas en una hoja de cálculo. Define tratamiento según el tipo de columna.
05 / PRACTICAR
Tu turno
Exporta una lectura con value=0 y una con valor ausente si el modelo lo permite.
Ver solución orientativa
Cero se escribe como 0 y la ausencia como un campo vacío o valor acordado; no se reemplazan ambos por el mismo dato.
06 / VERIFICAR
Cómo sabes que funciona
- Exportación coincide con los datos persistidos.
- Rangos grandes no construyen todas las filas en memoria.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
Correo SMTP nativo después del commit →Continuar en modo relato