> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datasnap.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Formato de Dados JSONL

> Entenda o formato JSONL (JSON Lines) usado pelo DataSnap para dados estruturados

## 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.

<Info>
  O formato JSONL é ideal para streaming de dados e trabalho eficiente com grandes volumes de informações estruturadas.
</Info>

## Estrutura básica

### Formato válido

Cada linha deve conter exatamente um objeto JSON:

```jsonl theme={null}
{"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`)

## Campo de Data Obrigatório (Data do Evento)

Para garantir a correta **ordenação, organização e busca** dos dados, é **obrigatório** definir um campo de data principal no seu modelo de dados, conhecido como **Data do Evento**.

<Warning>
  A ausência deste campo ou a configuração incorreta pode comprometer a performance das consultas e a organização temporal dos seus dados.
</Warning>

O sistema utiliza este campo para:

* Ordenação padrão dos registros
* Indexação e particionamento por tempo
* Otimização de filtros de período

Certifique-se de que seus arquivos JSONL contenham este campo preenchido corretamente em todos os registros.

## Tipos de dados suportados

### Tipos primitivos

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

### Arrays

```jsonl theme={null}
{"tags": ["vendas", "online", "promocao"], "categorias": [1, 2, 3]}
{"produtos": ["notebook", "mouse", "teclado"]}
```

### Objetos aninhados

```jsonl theme={null}
{"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

```jsonl theme={null}
{"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:

<CodeGroup>
  ```jsonl Recomendado theme={null}
  {"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}
  ```

  ```jsonl Evitar theme={null}
  {"id": 1, "nome": "João", "idade": 30}
  {"id": 2, "full_name": "Maria Santos", "age": 25, "status": "inactive"}
  {"identifier": 3, "nome": "Carlos"}
  ```
</CodeGroup>

### Nomenclatura de campos

Use nomes de campos consistentes e descritivos:

```jsonl theme={null}
{"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:

```jsonl theme={null}
{"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:

<CodeGroup>
  ```jsonl Válido theme={null}
  {"nome": "João", "idade": 30}
  {"nome": "Maria", "idade": 25}
  ```

  ```jsonl Inválido theme={null}
  {nome: "João", idade: 30}  // Aspas ausentes nas chaves
  {"nome": "Maria", "idade": 25,}  // Vírgula extra
  ```
</CodeGroup>

### Codificação de caracteres

Use UTF-8 para suportar caracteres especiais:

```jsonl theme={null}
{"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:

<CodeGroup>
  ```python Python theme={null}
  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")
  ```

  ```bash Bash theme={null}
  # Validar usando jq (Linux/Mac)
  cat dados.jsonl | while read line; do
    echo "$line" | jq . > /dev/null || echo "Erro na linha: $line"
  done

  # Contar linhas válidas
  cat dados.jsonl | jq -s length
  ```

  ```javascript JavaScript theme={null}
  const fs = require('fs');

  function validarJsonl(arquivo) {
      const conteudo = fs.readFileSync(arquivo, 'utf8');
      const linhas = conteudo.split('\n');
      let erros = 0;
      
      linhas.forEach((linha, index) => {
          linha = linha.trim();
          if (!linha) return; // Pular linhas vazias
          
          try {
              JSON.parse(linha);
              console.log(`✅ Linha ${index + 1}: válida`);
          } catch (error) {
              console.error(`❌ Linha ${index + 1}: ${error.message}`);
              erros++;
          }
      });
      
      return erros === 0;
  }
  ```
</CodeGroup>

## Conversão de formatos

### De CSV para JSONL

```python theme={null}
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

```python theme={null}
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 abaixo de 10MB:

```
- **Recomendado** (até 10MB): Performance otimizada
- **Muito grande** (>10MB): Pode causar timeouts e afetar experiência
```

### Compressão

Para arquivos grandes, use compressão antes do upload:

```bash theme={null}
# Comprimir arquivo JSONL
gzip dados.jsonl  # Resulta em dados.jsonl.gz

# O DataSnap aceita arquivos comprimidos automaticamente
```

## Exemplos práticos

### E-commerce

```jsonl theme={null}
{"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

```jsonl theme={null}
{"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

```jsonl theme={null}
{"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

<CardGroup cols={2}>
  <Card title="Upload de arquivos" icon="upload" href="/api-reference/endpoint/schema-upload-token-endpoint">
    ⚠️ Sistema antigo descontinuado - Use o novo sistema de tokens para upload
  </Card>

  <Card title="Consultas" icon="search" href="/essentials/consulta-dados">
    Aprenda a consultar seus dados de forma eficiente
  </Card>
</CardGroup>
