Actualizaciones de Conjuntos de Datos

Actualizar Conjuntos de Datos Existentes

Actualice conjuntos de datos existentes con nuevos datos provenientes de archivos CSV, paquetes ZIP o archivos binarios. Las actualizaciones preservan el ID del conjunto de datos y las configuraciones asociadas.

Actualizar Conjunto de Datos desde CSV

PUT /api/{tenantId}/{projectId}/dataset/{datasetId}/csv

Reemplaza los datos en un conjunto de datos existente con nuevos datos provenientes de un archivo CSV. El sistema detecta automáticamente el mapeo de columnas desde la configuración del conjunto de datos.

Parámetros de Ruta

Parámetro Tipo Requerido Descripción
tenantId GUID Identificador del inquilino
projectId GUID Identificador del proyecto
datasetId GUID Identificador del conjunto de datos a actualizar

Petición (multipart/form-data)

Campo Tipo Requerido Descripción
file archivo Archivo CSV con nuevos datos (máx 1GB)
cultureInfo cadena No Cultura para el análisis (predeterminado: "en-US")

Respuesta (200 OK)

{
  "datasetId": "550e8400-e29b-41d4-a716-446655440000",
  "caseCount": 5500,
  "eventCount": 165000,
  "invalidValueCount": 0,
  "skippedRowsCount": 0,
  "errors": [],
  "rowIssues": [],
  "statusCode": 200
}

Respuestas de Error

Solicitud Incorrecta (400):

dataset with id '{datasetId}' not found
can't update '{datasetName}' because it's not an original dataset

Actualizar Conjunto de Datos desde Paquete ZIP

PUT /api/{tenantId}/{projectId}/dataset/{datasetId}/package

Reemplaza los datos en un conjunto de datos existente con nuevos datos provenientes de un paquete ZIP.

Petición (multipart/form-data)

Campo Tipo Requerido Descripción
file archivo Archivo paquete ZIP con nuevos datos (máx 1GB)
cultureInfo cadena No Cultura para el análisis (predeterminado: "en-US")

Respuesta (200 OK)

Misma estructura que la respuesta de actualización desde CSV.

Respuesta de Error (422 Entidad No Procesable)

{
  "errors": ["Invalid package structure"],
  "rowIssues": [
    {
      "rowIndex": 15,
      "columnName": "Timestamp",
      "errorType": "ParseError",
      "outcome": "Skipped",
      "message": "Unable to parse date value"
    }
  ],
  "statusCode": 422
}

Actualizar Conjunto de Datos desde Archivo Binario

PUT /api/{tenantId}/{projectId}/dataset/{datasetId}/binary

Reemplaza los datos en un conjunto de datos existente con nuevos datos provenientes de un archivo en formato binario.

Petición (multipart/form-data)

Campo Tipo Requerido Descripción
file archivo Archivo binario con nuevos datos (máx 1GB)

Respuesta (200 OK)

Misma estructura que la respuesta de actualización desde CSV.

Restricciones de Actualización

  • Solo Conjuntos de Datos Originales: Solo los conjuntos de datos originales pueden actualizarse. Los conjuntos derivados de filtros u otras transformaciones no pueden actualizarse directamente.
  • Preservar Configuración: Las actualizaciones preservan el ID del conjunto de datos y todas las configuraciones asociadas (notebooks, bloques, etc.)
  • Consistencia de Columnas: Los nuevos datos deben tener la misma estructura de columnas que el conjunto de datos original.

Ejemplos de Implementación

cURL - Actualizar desde CSV

curl -X PUT "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/87654321-4321-4321-4321-210987654321/dataset/550e8400-e29b-41d4-a716-446655440000/csv" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "file=@updated_event_log.csv" \
  -F "cultureInfo=en-US"

cURL - Actualizar desde Paquete ZIP

curl -X PUT "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/87654321-4321-4321-4321-210987654321/dataset/550e8400-e29b-41d4-a716-446655440000/package" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "file=@updated_data_package.zip" \
  -F "cultureInfo=en-US"

Python

import requests

TENANT_ID = '12345678-1234-1234-1234-123456789012'
PROJECT_ID = '87654321-4321-4321-4321-210987654321'
BASE_URL = 'https://your-mindzie-instance.com'

class DatasetUpdater:
    def __init__(self, token):
        self.headers = {'Authorization': f'Bearer {token}'}

    def update_from_csv(self, dataset_id, file_path, culture='en-US'):
        """Actualizar conjunto de datos desde archivo CSV."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dataset/{dataset_id}/csv'

        with open(file_path, 'rb') as f:
            files = {'file': (file_path, f, 'text/csv')}
            data = {'cultureInfo': culture}

            response = requests.put(url, headers=self.headers, files=files, data=data)

        if response.ok:
            return response.json()
        else:
            raise Exception(f'Fallo la actualización: {response.text}')

    def update_from_package(self, dataset_id, file_path, culture='en-US'):
        """Actualizar conjunto de datos desde paquete ZIP."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dataset/{dataset_id}/package'

        with open(file_path, 'rb') as f:
            files = {'file': (file_path, f, 'application/zip')}
            data = {'cultureInfo': culture}

            response = requests.put(url, headers=self.headers, files=files, data=data)

        if response.ok:
            return response.json()
        elif response.status_code == 422:
            result = response.json()
            print(f"Errores de validación: {result['errors']}")
            for issue in result.get('rowIssues', []):
                print(f"  Fila {issue['rowIndex']}: {issue['message']}")
            raise Exception('Falló la validación de datos')
        else:
            raise Exception(f'Fallo la actualización: {response.text}')

    def update_from_binary(self, dataset_id, file_path):
        """Actualizar conjunto de datos desde archivo binario."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dataset/{dataset_id}/binary'

        with open(file_path, 'rb') as f:
            files = {'file': (file_path, f, 'application/octet-stream')}

            response = requests.put(url, headers=self.headers, files=files)

        if response.ok:
            return response.json()
        else:
            raise Exception(f'Fallo la actualización: {response.text}')

# Uso
updater = DatasetUpdater('your-auth-token')

# Actualizar desde CSV
result = updater.update_from_csv(
    '550e8400-e29b-41d4-a716-446655440000',
    'updated_event_log.csv'
)
print(f"Conjunto de datos actualizado: {result['datasetId']}")
print(f"Nuevo recuento de casos: {result['caseCount']}")
print(f"Nuevo recuento de eventos: {result['eventCount']}")

# Verificar problemas
if result['skippedRowsCount'] > 0:
    print(f"Advertencia: se omitieron {result['skippedRowsCount']} filas")
if result['invalidValueCount'] > 0:
    print(f"Advertencia: se encontraron {result['invalidValueCount']} valores inválidos")

JavaScript/Node.js

const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const PROJECT_ID = '87654321-4321-4321-4321-210987654321';
const BASE_URL = 'https://your-mindzie-instance.com';

class DatasetUpdater {
  constructor(token) {
    this.token = token;
  }

  async updateFromCsv(datasetId, file, culture = 'en-US') {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dataset/${datasetId}/csv`;

    const formData = new FormData();
    formData.append('file', file);
    formData.append('cultureInfo', culture);

    const response = await fetch(url, {
      method: 'PUT',
      headers: { 'Authorization': `Bearer ${this.token}` },
      body: formData
    });

    if (response.ok) {
      return await response.json();
    } else if (response.status === 422) {
      const result = await response.json();
      throw new Error(`Validación fallida: ${result.errors.join(', ')}`);
    } else {
      throw new Error(`Fallo la actualización: ${await response.text()}`);
    }
  }

  async updateFromPackage(datasetId, file, culture = 'en-US') {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dataset/${datasetId}/package`;

    const formData = new FormData();
    formData.append('file', file);
    formData.append('cultureInfo', culture);

    const response = await fetch(url, {
      method: 'PUT',
      headers: { 'Authorization': `Bearer ${this.token}` },
      body: formData
    });

    if (response.ok) {
      return await response.json();
    } else {
      const error = await response.json();
      throw new Error(`Fallo la actualización: ${error.errors?.join(', ') || response.statusText}`);
    }
  }
}

// Uso (navegador)
const updater = new DatasetUpdater('your-auth-token');
const fileInput = document.getElementById('updateFile');

fileInput.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const datasetId = '550e8400-e29b-41d4-a716-446655440000';

  try {
    const result = await updater.updateFromCsv(datasetId, file);

    console.log(`Actualizado: ${result.datasetId}`);
    console.log(`Nuevos casos: ${result.caseCount}`);
    console.log(`Nuevos eventos: ${result.eventCount}`);

    if (result.skippedRowsCount > 0) {
      console.warn(`Se omitieron ${result.skippedRowsCount} filas`);
    }
  } catch (error) {
    console.error('Fallo la actualización:', error.message);
  }
});

Campos de Respuesta

Campo Tipo Descripción
datasetId GUID ID del conjunto de datos actualizado
caseCount entero Número de casos únicos en los datos actualizados
eventCount entero Número total de eventos en los datos actualizados
invalidValueCount entero Número de valores inválidos encontrados
skippedRowsCount entero Número de filas omitidas por errores
errors array Lista de mensajes de error
rowIssues array Información detallada sobre problemas a nivel de fila
statusCode entero Código de estado HTTP

Estructura de Problemas en Filas

{
  "rowIndex": 15,
  "columnName": "Timestamp",
  "errorType": "ParseError",
  "outcome": "Skipped",
  "message": "Unable to parse date value '2024-13-45'"
}
Campo Descripción
rowIndex Número de fila con el problema
columnName Columna que contiene el valor problemático
errorType Tipo de error (ParseError, ValidationError, etc.)
outcome Resultado ocurrido (Skipped, DefaultValue, etc.)
message Descripción del error legible para humanos

Mejores Prácticas

  • Hacer Copia de Seguridad Primero: Considere exportar los datos actuales antes de actualizarlos
  • Verificar Estructura: Asegúrese de que los nuevos datos tengan la misma estructura de columnas
  • Revisar Resultados: Revise rowIssues y skippedRowsCount después de las actualizaciones
  • Probar Primero: Realice pruebas en un conjunto de datos que no sea de producción antes de actualizar
  • Configuración de Cultura: Use la cultura correcta para formatos de fecha y número