O que é JSONL?

JSONL (JSON Lines) é um formato de texto onde cada linha contém um objeto JSON válido e independente. É o formato padrão para upload de dados no DataSnap.
O formato JSONL é ideal para streaming de dados e processamento eficiente de grandes volumes de informações estruturadas.

Estrutura básica

Formato válido

Cada linha deve conter exatamente um objeto JSON:
{"id": 1, "nome": "João Silva", "idade": 30, "cidade": "São Paulo"}
{"id": 2, "nome": "Maria Santos", "idade": 25, "cidade": "Rio de Janeiro"}
{"id": 3, "nome": "Carlos Oliveira", "idade": 35, "cidade": "Belo Horizonte"}

Características importantes

  • Uma linha = um objeto: Cada linha representa um registro independente
  • JSON válido: Cada linha deve ser um JSON válido quando analisada individualmente
  • Sem vírgulas entre linhas: Diferente de arrays JSON, não há vírgulas separando os objetos
  • Quebras de linha: Cada objeto termina com uma quebra de linha (\n)

Tipos de dados suportados

Tipos primitivos

{"string": "texto", "number": 123, "boolean": true, "null_value": null}
{"decimal": 99.99, "integer": 42, "negative": -10}

Arrays

{"tags": ["vendas", "online", "promocao"], "categorias": [1, 2, 3]}
{"produtos": ["notebook", "mouse", "teclado"]}

Objetos aninhados

{"cliente": {"nome": "João", "email": "joao@email.com"}, "pedido": {"id": 123, "valor": 199.90}}
{"endereco": {"rua": "Rua A", "numero": 123, "cep": "01234-567"}}

Datas e timestamps

{"data_criacao": "2024-08-15T10:30:00Z", "data_nascimento": "1990-05-15"}
{"timestamp": "2024-08-15T10:30:00-03:00", "data_simples": "2024-08-15"}

Boas práticas

Consistência de schema

Mantenha a mesma estrutura de campos entre registros:
{"id": 1, "nome": "João", "idade": 30, "ativo": true}
{"id": 2, "nome": "Maria", "idade": 25, "ativo": false}
{"id": 3, "nome": "Carlos", "idade": 35, "ativo": true}

Nomenclatura de campos

Use nomes de campos consistentes e descritivos:
{"produto_id": 123, "nome_produto": "Notebook", "preco_unitario": 1999.90}
{"produto_id": 124, "nome_produto": "Mouse", "preco_unitario": 49.90}

Valores ausentes

Para campos opcionais, use null ou omita o campo:
{"id": 1, "nome": "João", "telefone": "11999999999", "email": "joao@email.com"}
{"id": 2, "nome": "Maria", "telefone": null, "email": "maria@email.com"}
{"id": 3, "nome": "Carlos", "email": "carlos@email.com"}

Validação de dados

Estrutura obrigatória

Garanta que cada linha seja um JSON válido:
{"nome": "João", "idade": 30}
{"nome": "Maria", "idade": 25}

Codificação de caracteres

Use UTF-8 para suportar caracteres especiais:
{"nome": "José da Silva", "cidade": "São Paulo", "observacao": "Cliente há 5 anos"}
{"nome": "María González", "cidade": "Buenos Aires", "nota": "Preferência por español"}

Ferramentas úteis

Validação local

Use estas ferramentas para validar seus arquivos JSONL:
import json

def validar_jsonl(arquivo):
    erros = []
    with open(arquivo, 'r', encoding='utf-8') as f:
        for linha_num, linha in enumerate(f, 1):
            linha = linha.strip()
            if not linha:  # Pular linhas vazias
                continue
            try:
                json.loads(linha)
                print(f"✅ Linha {linha_num}: válida")
            except json.JSONDecodeError as e:
                erro = f"❌ Linha {linha_num}: {e}"
                erros.append(erro)
                print(erro)
    
    return len(erros) == 0

# Uso
if validar_jsonl("dados.jsonl"):
    print("📋 Arquivo válido!")
else:
    print("⚠️ Arquivo contém erros")

Conversão de formatos

De CSV para JSONL

import csv
import json

def csv_para_jsonl(arquivo_csv, arquivo_jsonl):
    with open(arquivo_csv, 'r', encoding='utf-8') as csv_file:
        with open(arquivo_jsonl, 'w', encoding='utf-8') as jsonl_file:
            reader = csv.DictReader(csv_file)
            for row in reader:
                json.dump(row, jsonl_file, ensure_ascii=False)
                jsonl_file.write('\n')

# Uso
csv_para_jsonl('dados.csv', 'dados.jsonl')

De JSON array para JSONL

import json

def json_array_para_jsonl(arquivo_json, arquivo_jsonl):
    with open(arquivo_json, 'r', encoding='utf-8') as json_file:
        data = json.load(json_file)
        
    with open(arquivo_jsonl, 'w', encoding='utf-8') as jsonl_file:
        for item in data:
            json.dump(item, jsonl_file, ensure_ascii=False)
            jsonl_file.write('\n')

# Uso
json_array_para_jsonl('dados.json', 'dados.jsonl')

Otimizações

Tamanho de arquivo

Para melhor performance, mantenha arquivos entre 10MB e 100MB:
- **Muito pequeno** (<1MB): Overhead de processamento
- **Ideal** (10-100MB): Performance otimizada  
- **Muito grande** (>100MB): Pode causar timeouts

Compressão

Para arquivos grandes, use compressão antes do upload:
# Comprimir arquivo JSONL
gzip dados.jsonl  # Resulta em dados.jsonl.gz

# O DataSnap aceita arquivos comprimidos automaticamente

Exemplos práticos

E-commerce

{"pedido_id": "PED001", "cliente": "João Silva", "data": "2024-08-15", "itens": [{"produto": "Notebook", "preco": 1999.90, "qtd": 1}], "total": 1999.90}
{"pedido_id": "PED002", "cliente": "Maria Santos", "data": "2024-08-15", "itens": [{"produto": "Mouse", "preco": 49.90, "qtd": 2}], "total": 99.80}

Logs de aplicação

{"timestamp": "2024-08-15T10:30:00Z", "level": "INFO", "message": "Usuário logado", "user_id": 123, "ip": "192.168.1.1"}
{"timestamp": "2024-08-15T10:31:00Z", "level": "ERROR", "message": "Falha na conexão", "service": "database", "error_code": "DB001"}

Dados financeiros

{"data": "2024-08-15", "conta": "12345", "tipo": "credito", "valor": 1500.00, "descricao": "Salário", "categoria": "receita"}
{"data": "2024-08-15", "conta": "12345", "tipo": "debito", "valor": 250.00, "descricao": "Supermercado", "categoria": "alimentacao"}

Próximos passos