Gerenciando Tabelas Managed
Este guia mostra os fluxos completos da Managed Tables API: provisionamento do banco, criacao manual, upload de arquivos com inferencia de schema, e CRUD de linhas.
Quando usar: quando a sua aplicacao precisa armazenar dados estruturados proprios da company (planilhas, dados de calculo, listas operacionais) sem depender de um banco externo. Quando nao usar: se voce quer expor uma visualizacao salva como API (use Data API).
Pre-requisitos
- JWT do console (login normal — nao usa API key).
- Permissoes IAM atribuidas:
managed-tables:list,managed-tables:create,managed-tables:update,managed-tables:deletemanaged-tables:upload,managed-tables:data-read,managed-tables:data-write
- Roles managed que ja agregam tudo:
ConnectionManager,DataEngineer.
Visao geral dos fluxos
Workflow 1: Provisionamento
Toda company precisa provisionar sua area de armazenamento uma unica vez. Idempotente — chamadas subsequentes retornam o estado existente.
export TOKEN="eyJ..."
export API_BASE_URL="http://localhost:3100"
# 1. Verifica status
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: Criacao manual de tabela
Use quando voce ja sabe o schema. Nao requer arquivo.
# 1. Cria tabela
curl -X POST "$API_BASE_URL/api/v1/managed-tables" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "vendas_mensais",
"columns": [
{ "name": "produto", "display_name": "Produto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true },
{ "name": "data_venda", "display_name": "Data", "type": "date", "nullable": false }
]
}'
# Resposta:
# { "_id": "507f...", "display_name": "vendas_mensais", "columns": [...], ... }
# 2. Insere linhas
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rows": [
{ "produto": "Camisa", "valor": 89.90, "data_venda": "2026-01-15" },
{ "produto": "Calca", "valor": 159.90, "data_venda": "2026-01-15" }
]
}'
# → 201 { "inserted": 2 }
display_namee nome de coluna casam^[a-z_][a-z0-9_]*$.display_namee unico por company entre tabelas ativas.- Conflito retorna
400comerror_code: MANAGED_TABLE_DUPLICATE_NAME.
Workflow 3: Upload de arquivo (CSV/Excel/ZIP)
Fluxo de 2 passos com inferencia de schema. A API processa o arquivo de forma assincrona e o cliente confirma o schema antes da insercao final.
Etapa 1 — upload
curl -X POST "$API_BASE_URL/api/v1/managed-tables/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@vendas_2026.csv"
# → 201 { "job_id": "abc123", "status": "queued" }
Limites: ate 10 arquivos por chamada, 100MB total. Aceita .csv, .xlsx, .xls, .zip (zip e descompactado automaticamente).
Etapa 2 — polling do status
curl "$API_BASE_URL/api/v1/managed-tables/upload-jobs/abc123" \
-H "Authorization: Bearer $TOKEN"
Estados que voce vai observar (em ordem):
| Status | Significado | Acao do cliente |
|---|---|---|
queued | Aguardando processamento | Continuar polling |
analisando | API processando arquivo | Mostrar spinner |
waiting_confirm | Schema inferido pronto | Renderizar UI de confirmacao com inferred_schema |
inserting | Insercao em andamento | Mostrar progresso (progress.processed_rows) |
done | Tabela criada/atualizada | Redirecionar para user_table_id |
failed | Erro | Mostrar error |
Quando status === "waiting_confirm", o body contem:
{
"status": "waiting_confirm",
"inferred_schema": {
"suggested_table_name": "vendas_2026",
"columns": [
{ "name": "produto", "display_name": "Produto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
],
"sample_rows": [{ "produto": "Camisa", "valor": "89.90" }],
"total_row_count_estimate": 1500
}
}
Etapa 3 — confirmar schema
O usuario pode editar nomes de coluna, tipos e display_name da tabela 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": "vendas_2026",
"columns": [
{ "name": "produto", "display_name": "Produto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
]
}'
# → 200 { "status": "inserting" }
Continue polling ate status === "done". O user_table_id no job aponta para a tabela criada.
Workflow 4: Append/Replace em tabela existente
Anexa novas linhas a uma tabela ja criada (ou substitui o conteudo todo).
# Append em tabela existente
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@vendas_fevereiro.csv" \
-F "mode=append"
# Replace (substitui tudo)
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@vendas_completo.csv" \
-F "mode=replace"
display_nameda tabela existente e reusado — o regex^[a-z_][a-z0-9_]*$nao e aplicado (suporta tabelas legadas).- Schema confirmado deve casar com schema da tabela existente — colunas extras causam falha no insert.
replacee atomico — todo o conteudo e substituido em uma unica operacao (sem estado parcial visivel).
Workflow 5: CRUD de linhas
Operacoes ponto-a-ponto sobre as linhas de uma tabela.
# Listar (paginado)
curl "$API_BASE_URL/api/v1/managed-tables/507f.../data?page=1&per_page=50&sort_by=-data_venda" \
-H "Authorization: Bearer $TOKEN"
# → { "total": 1500, "quantity": 50, "records": [{ "id": "uuid", "produto": "X", ... }] }
# Inserir
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "rows": [{ "produto": "Z", "valor": 50 }] }'
# Atualizar linha
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 }'
# Deletar
curl -X DELETE "$API_BASE_URL/api/v1/managed-tables/507f.../data/<rowId>" \
-H "Authorization: Bearer $TOKEN"
# → 204 No Content
rowId e o identificador interno da linha (geralmente UUID gerado no insert). Aparece como id em cada item de records.
Workflow 6: Soft-delete da tabela
Listagens (GET /v1/managed-tables) ja excluem tabelas arquivadas, entao a tabela some imediatamente. Restauracao nao e exposta pela API — abra um ticket de suporte se precisar reverter.
Tipos de coluna suportados
| Tipo | PostgreSQL DDL | Exemplo |
|---|---|---|
text | TEXT | "abc" |
integer | BIGINT | 42 |
decimal | NUMERIC | 89.90 |
boolean | BOOLEAN | true |
date | DATE | "2026-01-15" |
datetime | TIMESTAMPTZ | "2026-01-15T10:30:00Z" |
Tratamento de erros
| HTTP | Codigo | Causa comum | Acao |
|---|---|---|---|
| 400 | MANAGED_TABLE_DUPLICATE_NAME | display_name ja existe ativo | Pedir outro nome ao usuario |
| 400 | - | Banco nao provisionado | Chamar POST /provision antes |
| 400 | - | Job nao em waiting_confirm | Continuar polling antes de confirmar |
| 401 | - | JWT ausente/expirado | Refresh token |
| 403 | - | Sem permissao IAM | Conferir role do usuario |
| 404 | - | Tabela/linha/job inexistente | Reler estado do recurso |
| 422 | - | Schema invalido (regex, tipo, campo obrigatorio) | Mostrar erro especifico ao usuario |
| 500 | - | Erro interno | Retry com backoff; logar request_id |
Boas praticas
- Nao chame
POST /provisionem loop — e idempotente, mas cada chamada e mais cara. ChequeGET /statusprimeiro. - Polling com backoff exponencial — comece em 1s, dobre ate 10s. Job de upload pode levar segundos a minutos dependendo do tamanho.
- Mostre
progress.processed_rows / progress.total_rowsduranteinsertingpara feedback ao usuario em arquivos grandes. - Valide o tamanho dos arquivos no frontend antes do upload — backend rejeita >100MB total.
- Reuse
mode=appendpara uploads incrementais; nao crie nova tabela cada vez. - Para queries customizadas em cima das tabelas managed, exponha como Visualization e publique via Data API. Managed Tables nao expoe SQL livre.
Referencia completa
Para o contrato detalhado de cada endpoint (todos os campos, status codes, exemplos de erro), veja Managed Tables API Reference.