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

# Catálogo do SeaweedFS

> Neste guia, mostraremos como consultar seus dados usando o ClickHouse e o catálogo Iceberg do SeaweedFS.

export const ExperimentalBadge = () => {
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#experimental-features" className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Recurso experimental
        </a>;
};

<ExperimentalBadge />

<Note>
  A integração com o catálogo SeaweedFS funciona apenas com tabelas Iceberg.
</Note>

O ClickHouse oferece integração com vários catálogos (Unity, Glue, REST, Polaris etc.). Este guia apresenta as etapas para consultar seus dados usando o ClickHouse e o catálogo [SeaweedFS](https://github.com/seaweedfs/seaweedfs).

O SeaweedFS é um armazenamento distribuído de arquivos e objetos de código aberto com um gateway compatível com S3. Seus S3 Table Buckets fornecem os dois componentes de uma implantação do Iceberg: o catálogo REST do Iceberg embutido fornece os metadados das tabelas, e o bucket de tabelas armazena os dados das tabelas como arquivos Parquet no mesmo endpoint S3:

* **Serviço único** - os metadados do catálogo e os dados Parquet são fornecidos por um único processo, sem um banco de dados de metadados separado
* Conformidade da **API REST** com a especificação do catálogo REST do Iceberg
* **Manutenção no servidor** - compactação automática de arquivos Parquet e expiração de snapshots, sem serviço de manutenção externo

<Note>
  Como este recurso é experimental, você precisará ativá-lo usando:
  `SET allow_experimental_database_iceberg = 1;`
</Note>

<div id="local-development-setup">
  ## Configuração para desenvolvimento local
</div>

Para desenvolvimento e testes locais, você pode executar o SeaweedFS e o ClickHouse com o Docker Compose. Essa abordagem é ideal para aprendizado, prototipagem e ambientes de desenvolvimento.

<div id="local-prerequisites">
  ### Pré-requisitos
</div>

1. **Docker e Docker Compose**: verifique se o Docker está instalado e em execução
2. **Versões**: SeaweedFS 4.42 ou posterior; ClickHouse 26.8 ou posterior (as versões desde a 25.8 podem ler e inserir, mas a criação de tabelas pelo catálogo requer a versão 26.8)
3. **Python com PyIceberg** (opcional): usado abaixo para inserir dados de exemplo

<div id="setting-up-local-seaweedfs-catalog">
  ### Configurar o catálogo local do SeaweedFS
</div>

**Etapa 1:** Crie uma nova pasta para executar o exemplo e, em seguida, crie um arquivo `s3config.json` com as credenciais do gateway S3 e do catálogo:

```json theme={null}
{
  "identities": [
    {
      "name": "analyst",
      "credentials": [
        {
          "accessKey": "tutorialkey",
          "secretKey": "tutorialsecret"
        }
      ],
      "actions": ["Admin", "Read", "Write", "List", "Tagging"]
    }
  ]
}
```

**Etapa 2:** Crie um arquivo `docker-compose.yml` com a seguinte configuração:

```yaml theme={null}
services:
  seaweedfs:
    image: chrislusf/seaweedfs:latest
    command: mini -dir=/data -s3.config=/etc/seaweedfs/s3config.json -tableBucket=analytics
    ports:
      - "8333:8333"   # S3 endpoint
      - "8181:8181"   # Iceberg REST catalog
    volumes:
      - ./s3config.json:/etc/seaweedfs/s3config.json
      - seaweedfs_data:/data
    networks:
      - iceberg_net

  clickhouse:
    image: clickhouse/clickhouse-server:latest
    container_name: seaweedfs-clickhouse
    ports:
      - "8123:8123"
      - "9000:9000"
    depends_on:
      - seaweedfs
    networks:
      - iceberg_net

volumes:
  seaweedfs_data:

networks:
  iceberg_net:
    driver: bridge
```

O comando `mini` inicia toda a stack do SeaweedFS em um único container. A flag `-tableBucket=analytics` cria antecipadamente um bucket do S3 Tables chamado `analytics`, que funciona como warehouse do Iceberg.

**Passo 3:** Execute o seguinte comando para iniciar os serviços:

```bash theme={null}
docker compose up -d
```

<div id="seeding-sample-data">
  ### Inserindo dados de exemplo
</div>

O catálogo está inicialmente vazio. Crie uma tabela e acrescente algumas linhas usando o PyIceberg (`pip install pyiceberg pyarrow`):

```python theme={null}
import pyarrow as pa
from pyiceberg.catalog.rest import RestCatalog

catalog = RestCatalog(
    "seaweedfs",
    uri="http://localhost:8181",
    warehouse="s3://analytics",
    credential="tutorialkey:tutorialsecret",
    **{
        "s3.endpoint": "http://localhost:8333",
        "s3.access-key-id": "tutorialkey",
        "s3.secret-access-key": "tutorialsecret",
        "s3.region": "us-east-1",
        "s3.path-style-access": "true",
    },
)

rows = pa.table({
    "id": pa.array([1, 2, 3, 4, 5, 6], pa.int64()),
    "region": ["NA", "EU", "EU", "APAC", "NA", "EU"],
    "amount": pa.array([12.5, 40.0, 7.25, 99.9, 3.5, 61.0], pa.float64()),
})

catalog.create_namespace("sales")
table = catalog.create_table("sales.orders", schema=rows.schema)
table.append(rows)
```

<div id="connecting-to-local-seaweedfs-catalog">
  ### Como se conectar ao catálogo local do SeaweedFS
</div>

Conecte-se ao contêiner do ClickHouse:

```bash theme={null}
docker exec -it seaweedfs-clickhouse clickhouse-client
```

Em seguida, crie a conexão com o banco de dados no catálogo do SeaweedFS:

```sql theme={null}
SET allow_experimental_database_iceberg = 1;

CREATE DATABASE lake
ENGINE = DataLakeCatalog('http://seaweedfs:8181/v1', 'tutorialkey', 'tutorialsecret')
SETTINGS catalog_type = 'rest',
    warehouse = 's3://analytics',
    storage_endpoint = 'http://seaweedfs:8333/analytics',
    catalog_credential = 'tutorialkey:tutorialsecret',
    oauth_server_uri = 'http://seaweedfs:8181/v1/oauth/tokens'
```

Os argumentos do engine contêm as credenciais do S3 usadas pelo ClickHouse para ler os dados da tabela, enquanto `catalog_credential` e `oauth_server_uri` autenticam no próprio catálogo por meio do fluxo OAuth2 de credenciais de cliente. O SeaweedFS aceita a mesma chave de acesso e chave secreta para ambos.

<div id="querying-seaweedfs-catalog-tables-using-clickhouse">
  ## Consultando tabelas do catálogo do SeaweedFS com o ClickHouse
</div>

Agora que a conexão foi estabelecida, você pode começar a fazer consultas por meio do catálogo do SeaweedFS. Por exemplo:

```sql theme={null}
USE lake;

SHOW TABLES;
```

```response theme={null}
┌─name─────────┐
│ sales.orders │
└──────────────┘
```

<Info>
  **Backticks obrigatórios**

  Os backticks são obrigatórios porque o ClickHouse não oferece suporte a mais de um espaço de nomes.
</Info>

Para consultar uma tabela:

```sql theme={null}
SELECT region, sum(amount) AS total
FROM `sales.orders`
GROUP BY region
ORDER BY total DESC;
```

```response theme={null}
┌─region─┬──total─┐
│ EU     │ 108.25 │
│ APAC   │   99.9 │
│ NA     │     16 │
└────────┴────────┘
```

<div id="creating-tables-and-writing-data-from-clickhouse">
  ## Criar tabelas e gravar dados do ClickHouse
</div>

Você também pode criar tabelas no catálogo do SeaweedFS e gravar dados nelas diretamente do ClickHouse:

```sql theme={null}
SET allow_experimental_database_iceberg = 1;
SET allow_experimental_insert_into_iceberg = 1;
SET write_full_path_in_iceberg_metadata = 1;

CREATE TABLE lake.`sales.returns` (id Int64, reason String)
ENGINE = IcebergS3('http://seaweedfs:8333/analytics/sales/returns/', 'tutorialkey', 'tutorialsecret');

INSERT INTO lake.`sales.returns` VALUES (1, 'damaged'), (2, 'wrong size');

SELECT * FROM lake.`sales.returns` ORDER BY id;
```

```response theme={null}
┌─id─┬─reason─────┐
│  1 │ damaged    │
│  2 │ wrong size │
└────┴────────────┘
```

A cláusula do engine `IcebergS3` especifica o caminho de armazenamento da nova tabela, e `write_full_path_in_iceberg_metadata` faz com que o ClickHouse registre a localização completa da tabela no catálogo.

<Note>
  A criação de tabelas por meio de um catálogo requer o ClickHouse 26.8 ou posterior. As versões 26.4 a 26.7 gravam os arquivos da tabela antes de registrar o espaço de nomes, o que o SeaweedFS rejeita, a menos que o espaço de nomes já exista no catálogo; versões anteriores à 26.4 parecem funcionar, mas os arquivos da tabela são gravados no armazenamento de objetos sem serem registrados no catálogo.
</Note>

Quando o ClickHouse confirma um insert, o catálogo do SeaweedFS corrige metadados que o writer experimental ainda não produz: preenche IDs de campo ausentes nos manifests, reescreve caminhos de arquivos relativos ao bucket como localizações absolutas e atribui um mapeamento de nomes padrão à tabela. Leitores rigorosos, como PyIceberg e Spark, podem então ler as linhas gravadas pelo ClickHouse. Isso requer o SeaweedFS 4.42 ou posterior.

<div id="loading-data-from-your-data-lake-into-clickhouse">
  ## Carregando dados do seu lago de dados para o ClickHouse
</div>

Se precisar carregar dados do catálogo do SeaweedFS no ClickHouse, comece criando uma tabela local no ClickHouse:

```sql theme={null}
CREATE TABLE default.orders
(
    `id` Int64,
    `region` String,
    `amount` Float64
)
ENGINE = MergeTree()
ORDER BY (region, id);
```

Em seguida, carregue os dados da tabela do catálogo do SeaweedFS usando um `INSERT INTO SELECT`:

```sql theme={null}
INSERT INTO default.orders
SELECT * FROM lake.`sales.orders`;
```
