Saltar al contenido principal

Gestionando Tablas Managed

Esta guia muestra los flujos completos de la API de Managed Tables: provisionamiento del banco, creacion manual, upload de archivos con inferencia de schema, y CRUD de filas.

Cuando usar: cuando tu aplicacion necesita almacenar datos estructurados propios de la company (planillas, datos de calculo, listas operacionales) sin depender de un banco externo. Cuando no usar: si quieres exponer una visualizacion guardada como API (usa Data API).

Pre-requisitos​

  • JWT del console (login normal — no usa API key).
  • Permisos IAM asignados:
    • managed-tables:list, managed-tables:create, managed-tables:update, managed-tables:delete
    • managed-tables:upload, managed-tables:data-read, managed-tables:data-write
  • Roles managed que ya agregan todo: ConnectionManager, DataEngineer.

Vision general de los flujos​

Workflow 1: Provisionamiento​

Cada company debe provisionar su area de almacenamiento una unica vez. Idempotente — llamadas subsiguientes devuelven el estado existente.

export TOKEN="eyJ..."
export API_BASE_URL="http://localhost:3100"

# 1. Verifica estado
curl "$API_BASE_URL/api/v1/managed-tables/status" \
-H "Authorization: Bearer $TOKEN"
# → { "provisioned": false, "connection_id": null }

# 2. Provisiona (idempotente)
curl -X POST "$API_BASE_URL/api/v1/managed-tables/provision" \
-H "Authorization: Bearer $TOKEN"
# → { "provisioned": true, "connection_id": "507f..." }

Workflow 2: Creacion manual de tabla​

Usalo cuando ya conoces el schema. No requiere archivo.

# 1. Crear tabla
curl -X POST "$API_BASE_URL/api/v1/managed-tables" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "ventas_mensuales",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true },
{ "name": "fecha_venta", "display_name": "Fecha", "type": "date", "nullable": false }
]
}'

# Respuesta:
# { "_id": "507f...", "display_name": "ventas_mensuales", "columns": [...], ... }

# 2. Insertar filas
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rows": [
{ "producto": "Camisa", "valor": 89.90, "fecha_venta": "2026-01-15" },
{ "producto": "Pantalon", "valor": 159.90, "fecha_venta": "2026-01-15" }
]
}'
# → 201 { "inserted": 2 }
Reglas de nombre
  • display_name y nombre de columna coinciden con ^[a-z_][a-z0-9_]*$.
  • display_name es unico por company entre tablas activas.
  • Conflicto devuelve 400 con error_code: MANAGED_TABLE_DUPLICATE_NAME.

Workflow 3: Upload de archivo (CSV/Excel/ZIP)​

Flujo de 2 pasos con inferencia de schema. La API procesa el archivo de forma asincrona y el cliente confirma el schema antes de la insercion final.

Etapa 1 — upload​

curl -X POST "$API_BASE_URL/api/v1/managed-tables/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_2026.csv"
# → 201 { "job_id": "abc123", "status": "queued" }

Limites: hasta 10 archivos por llamada, 100MB total. Acepta .csv, .xlsx, .xls, .zip (zip es descomprimido automaticamente).

Etapa 2 — polling del estado​

curl "$API_BASE_URL/api/v1/managed-tables/upload-jobs/abc123" \
-H "Authorization: Bearer $TOKEN"

Estados que vas a observar (en orden):

EstadoSignificadoAccion del cliente
queuedEsperando procesamientoContinuar polling
analisandoAPI procesando archivoMostrar spinner
waiting_confirmSchema inferido listoRenderizar UI de confirmacion con inferred_schema
insertingInsercion en cursoMostrar progreso (progress.processed_rows)
doneTabla creada/actualizadaRedirigir a user_table_id
failedErrorMostrar error

Cuando status === "waiting_confirm", el body contiene:

{
"status": "waiting_confirm",
"inferred_schema": {
"suggested_table_name": "ventas_2026",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
],
"sample_rows": [{ "producto": "Camisa", "valor": "89.90" }],
"total_row_count_estimate": 1500
}
}

Etapa 3 — confirmar schema​

El usuario puede editar nombres de columna, tipos y display_name de la tabla antes de confirmar:

curl -X POST "$API_BASE_URL/api/v1/managed-tables/upload-jobs/abc123/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "ventas_2026",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
]
}'
# → 200 { "status": "inserting" }

Continua polling hasta status === "done". El user_table_id en el job apunta a la tabla creada.

Workflow 4: Append/Replace en tabla existente​

Anexa nuevas filas a una tabla ya creada (o sustituye todo el contenido).

# Append en tabla existente
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_febrero.csv" \
-F "mode=append"

# Replace (sustituye todo)
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_completo.csv" \
-F "mode=replace"
Diferencias en append/replace
  • display_name de la tabla existente es reusado — el regex ^[a-z_][a-z0-9_]*$ no se aplica (soporta tablas legacy).
  • Schema confirmado debe coincidir con el schema de la tabla existente — columnas extras causan falla en el insert.
  • replace es atomico — todo el contenido es sustituido en una unica operacion (sin estado parcial visible).

Workflow 5: CRUD de filas​

Operaciones punto-a-punto sobre las filas de una tabla.

# Listar (paginado)
curl "$API_BASE_URL/api/v1/managed-tables/507f.../data?page=1&per_page=50&sort_by=-fecha_venta" \
-H "Authorization: Bearer $TOKEN"
# → { "total": 1500, "quantity": 50, "records": [{ "id": "uuid", "producto": "X", ... }] }

# Insertar
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "rows": [{ "producto": "Z", "valor": 50 }] }'

# Actualizar fila
curl -X PUT "$API_BASE_URL/api/v1/managed-tables/507f.../data/<rowId>" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "valor": 99.90 }'

# Eliminar
curl -X DELETE "$API_BASE_URL/api/v1/managed-tables/507f.../data/<rowId>" \
-H "Authorization: Bearer $TOKEN"
# → 204 No Content

rowId es el identificador interno de la fila (generalmente UUID generado en el insert). Aparece como id en cada item de records.

Workflow 6: Soft-delete de la tabla​

Listados (GET /v1/managed-tables) ya excluyen tablas archivadas, asi que la tabla desaparece inmediatamente. Restauracion no es expuesta por la API — abre un ticket de soporte si necesitas revertir.

Tipos de columna soportados​

TipoPostgreSQL DDLEjemplo
textTEXT"abc"
integerBIGINT42
decimalNUMERIC89.90
booleanBOOLEANtrue
dateDATE"2026-01-15"
datetimeTIMESTAMPTZ"2026-01-15T10:30:00Z"

Tratamiento de errores​

HTTPCodigoCausa comunAccion
400MANAGED_TABLE_DUPLICATE_NAMEdisplay_name ya existe activoPedir otro nombre al usuario
400-Banco no provisionadoLlamar POST /provision antes
400-Job no esta en waiting_confirmContinuar polling antes de confirmar
401-JWT ausente/expiradoRefresh token
403-Sin permiso IAMVerificar el role del usuario
404-Tabla/fila/job inexistenteReleer estado del recurso
422-Schema invalido (regex, tipo, campo obligatorio)Mostrar error especifico al usuario
500-Error internoRetry con backoff; loguear request_id

Buenas practicas​

  • No llames POST /provision en loop — es idempotente, pero cada llamada es mas costosa. Verifica GET /status primero.
  • Polling con backoff exponencial — empieza en 1s, duplica hasta 10s. Job de upload puede llevar segundos a minutos dependiendo del tamano.
  • Muestra progress.processed_rows / progress.total_rows durante inserting para feedback al usuario en archivos grandes.
  • Valida el tamano de los archivos en el frontend antes del upload — backend rechaza >100MB total.
  • Reusa mode=append para uploads incrementales; no crees nueva tabla cada vez.
  • Para queries customizadas sobre las tablas managed, exponlas como Visualization y publicalas via Data API. Managed Tables no expone SQL libre.

Referencia completa​

Para el contrato detallado de cada endpoint (todos los campos, status codes, ejemplos de error), ve Managed Tables API Reference.