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

> Neste guia, mostraremos como consultar seus dados usando o ClickHouse e o Catálogo do Lakekeeper.

export const ExperimentalBadge = () => {
  return <div 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. <u><a href="/docs/docs/beta-and-experimental-features#experimental-features">Saiba mais.</a></u>
        </div>;
};

<ExperimentalBadge />

<Note>
  A integração com o catálogo do Lakekeeper funciona apenas com tabelas Iceberg.
  Esta integração oferece suporte tanto ao AWS S3 quanto a outros provedores de armazenamento em nuvem.
</Note>

O ClickHouse oferece suporte à integração com vários catálogos (Unity, Glue, REST, Polaris etc.). Este guia orienta você nas etapas para consultar seus dados usando o ClickHouse e o catálogo [Lakekeeper](https://docs.lakekeeper.io/).

O Lakekeeper é uma implementação open source de catálogo REST para Apache Iceberg que oferece:

* Implementação **nativa em Rust** para alto desempenho e confiabilidade
* **Conformidade da API REST** com a especificação de catálogo REST do Iceberg
* Integração com **armazenamento em nuvem** compatível com S3

<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 usar uma configuração do Lakekeeper em contêineres. 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. **Configuração de exemplo**: Você pode usar a configuração do Lakekeeper com `docker-compose`

<div id="setting-up-local-lakekeeper-catalog">
  ### Configurando o catálogo local do Lakekeeper
</div>

Você pode usar a [configuração oficial do Docker Compose do Lakekeeper](https://github.com/lakekeeper/lakekeeper/tree/main/examples/minimal), que fornece um ambiente completo com Lakekeeper, backend de metadados PostgreSQL e MinIO para armazenamento de objetos.

**Etapa 1:** Crie uma nova pasta para executar o exemplo e, em seguida, crie um arquivo `docker-compose.yml` com a seguinte configuração:

```yaml theme={null}
version: '3.8'

services:
  lakekeeper:
    image: quay.io/lakekeeper/catalog:latest
    environment:
      - LAKEKEEPER__PG_ENCRYPTION_KEY=This-is-NOT-Secure!
      - LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://postgres:postgres@db:5432/postgres
      - LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://postgres:postgres@db:5432/postgres
      - RUST_LOG=info
    command: ["serve"]
    healthcheck:
      test: ["CMD", "/home/nonroot/lakekeeper", "healthcheck"]
      interval: 1s
      timeout: 10s
      retries: 10
      start_period: 30s
    depends_on:
      migrate:
        condition: service_completed_successfully
      db:
        condition: service_healthy
      minio:
        condition: service_healthy
    ports:
      - 8181:8181
    networks:
      - iceberg_net

  migrate:
    image: quay.io/lakekeeper/catalog:latest-main
    environment:
      - LAKEKEEPER__PG_ENCRYPTION_KEY=This-is-NOT-Secure!
      - LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://postgres:postgres@db:5432/postgres
      - LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://postgres:postgres@db:5432/postgres
      - RUST_LOG=info
    restart: "no"
    command: ["migrate"]
    depends_on:
      db:
        condition: service_healthy
    networks:
      - iceberg_net

  bootstrap:
    image: curlimages/curl
    depends_on:
      lakekeeper:
        condition: service_healthy
    restart: "no"
    command:
      - -w
      - "%{http_code}"
      - "-X"
      - "POST"
      - "-v"
      - "http://lakekeeper:8181/management/v1/bootstrap"
      - "-H"
      - "Content-Type: application/json"
      - "--data"
      - '{"accept-terms-of-use": true}'
      - "-o"
      - "/dev/null"
    networks:
      - iceberg_net

  initialwarehouse:
    image: curlimages/curl
    depends_on:
      lakekeeper:
        condition: service_healthy
      bootstrap:
        condition: service_completed_successfully
    restart: "no"
    command:
      - -w
      - "%{http_code}"
      - "-X"
      - "POST"
      - "-v"
      - "http://lakekeeper:8181/management/v1/warehouse"
      - "-H"
      - "Content-Type: application/json"
      - "--data"
      - '{"warehouse-name": "demo", "project-id": "00000000-0000-0000-0000-000000000000", "storage-profile": {"type": "s3", "bucket": "warehouse-rest", "key-prefix": "", "assume-role-arn": null, "endpoint": "http://minio:9000", "region": "local-01", "path-style-access": true, "flavor": "minio", "sts-enabled": true}, "storage-credential": {"type": "s3", "credential-type": "access-key", "aws-access-key-id": "minio", "aws-secret-access-key": "ClickHouse_Minio_P@ssw0rd"}}'
      - "-o"
      - "/dev/null"
    networks:
      - iceberg_net

  db:
    image: bitnami/postgresql:16.3.0
    environment:
      - POSTGRESQL_USERNAME=postgres
      - POSTGRESQL_PASSWORD=postgres
      - POSTGRESQL_DATABASE=postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -p 5432 -d postgres"]
      interval: 2s
      timeout: 10s
      retries: 5
      start_period: 10s
    volumes:
      - postgres_data:/bitnami/postgresql
    networks:
      - iceberg_net

  minio:
    image: bitnami/minio:2025.4.22
    environment:
      - MINIO_ROOT_USER=minio
      - MINIO_ROOT_PASSWORD=ClickHouse_Minio_P@ssw0rd
      - MINIO_API_PORT_NUMBER=9000
      - MINIO_CONSOLE_PORT_NUMBER=9001
      - MINIO_SCHEME=http
      - MINIO_DEFAULT_BUCKETS=warehouse-rest
    networks: 
      iceberg_net:
        aliases:
          - warehouse-rest.minio
    ports:
      - "9002:9000"
      - "9003:9001"
    healthcheck:
      test: ["CMD", "mc", "ls", "local", "|", "grep", "warehouse-rest"]
      interval: 2s
      timeout: 10s
      retries: 3
      start_period: 15s
    volumes:
      - minio_data:/bitnami/minio/data

  clickhouse:
    image: clickhouse/clickhouse-server:head
    container_name: lakekeeper-clickhouse
    user: '0:0'  # Garante permissões de root
    ports:
      - "8123:8123"
      - "9000:9000"
    volumes:
      - clickhouse_data:/var/lib/clickhouse
      - ./clickhouse/data_import:/var/lib/clickhouse/data_import  # Monta a pasta do dataset
    networks:
      - iceberg_net
    environment:
      - CLICKHOUSE_DB=default
      - CLICKHOUSE_USER=default
      - CLICKHOUSE_DO_NOT_CHOWN=1
      - CLICKHOUSE_PASSWORD=
    depends_on:
      lakekeeper:
        condition: service_healthy
      minio:
        condition: service_healthy

volumes:
  postgres_data:
  minio_data:
  clickhouse_data:

networks:
  iceberg_net:
    driver: bridge
```

**Etapa 2:** Execute o seguinte comando para iniciar os serviços:

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

**Etapa 3:** Aguarde até que todos os serviços estejam prontos. Você pode verificar os logs:

```bash theme={null}
docker-compose logs -f
```

<Note>
  A configuração do Lakekeeper exige que os dados de exemplo sejam carregados primeiro nas tabelas Iceberg. Certifique-se de que o ambiente tenha criado e populado as tabelas antes de tentar fazer consultas nelas pelo ClickHouse. A disponibilidade das tabelas depende da configuração específica do docker-compose e dos scripts de carregamento dos dados de exemplo.
</Note>

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

Conecte-se ao seu contêiner do ClickHouse:

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

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

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

CREATE DATABASE demo
ENGINE = DataLakeCatalog('http://lakekeeper:8181/catalog', 'minio', 'ClickHouse_Minio_P@ssw0rd')
SETTINGS catalog_type = 'rest', storage_endpoint = 'http://minio:9002/warehouse-rest', warehouse = 'demo'
```

<div id="querying-lakekeeper-catalog-tables-using-clickhouse">
  ## Consultando tabelas do catálogo Lakekeeper usando o ClickHouse
</div>

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

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

SHOW TABLES;
```

Se a sua configuração incluir dados de exemplo (como o conjunto de dados de táxi), você deverá ver tabelas como:

```response theme={null}
┌─name──────────┐
│ default.taxis │
└───────────────┘
```

<Note>
  Se você não vir nenhuma tabela, isso geralmente significa que:

  1. O ambiente ainda não criou as tabelas de exemplo
  2. O serviço de catálogo do Lakekeeper ainda não foi totalmente inicializado
  3. O processo de carregamento dos dados de exemplo ainda não foi concluído

  Você pode verificar os logs do Spark para acompanhar o progresso da criação das tabelas:

  ```bash theme={null}
  docker-compose logs spark
  ```
</Note>

Para consultar uma tabela (se estiver disponível):

```sql theme={null}
SELECT count(*) FROM `default.taxis`;
```

```response theme={null}
┌─count()─┐
│ 2171187 │
└─────────┘
```

<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 inspecionar a DDL da tabela:

```sql theme={null}
SHOW CREATE TABLE `default.taxis`;
```

```response theme={null}
┌─statement─────────────────────────────────────────────────────────────────────────────────────┐
│ CREATE TABLE demo.`default.taxis`                                                             │
│ (                                                                                             │
│     `VendorID` Nullable(Int64),                                                               │
│     `tpep_pickup_datetime` Nullable(DateTime64(6)),                                           │
│     `tpep_dropoff_datetime` Nullable(DateTime64(6)),                                          │
│     `passenger_count` Nullable(Float64),                                                      │
│     `trip_distance` Nullable(Float64),                                                        │
│     `RatecodeID` Nullable(Float64),                                                           │
│     `store_and_fwd_flag` Nullable(String),                                                    │
│     `PULocationID` Nullable(Int64),                                                           │
│     `DOLocationID` Nullable(Int64),                                                           │
│     `payment_type` Nullable(Int64),                                                           │
│     `fare_amount` Nullable(Float64),                                                          │
│     `extra` Nullable(Float64),                                                                │
│     `mta_tax` Nullable(Float64),                                                              │
│     `tip_amount` Nullable(Float64),                                                           │
│     `tolls_amount` Nullable(Float64),                                                         │
│     `improvement_surcharge` Nullable(Float64),                                                │
│     `total_amount` Nullable(Float64),                                                         │
│     `congestion_surcharge` Nullable(Float64),                                                 │
│     `airport_fee` Nullable(Float64)                                                           │
│ )                                                                                             │
│ ENGINE = Iceberg('http://minio:9002/warehouse-rest/warehouse/default/taxis/', 'minio', '[HIDDEN]') │
└───────────────────────────────────────────────────────────────────────────────────────────────┘
```

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

Se você precisar carregar dados do catálogo do Lakekeeper para o ClickHouse, comece criando uma tabela local no ClickHouse:

```sql theme={null}
CREATE TABLE taxis
(
    `VendorID` Int64,
    `tpep_pickup_datetime` DateTime64(6),
    `tpep_dropoff_datetime` DateTime64(6),
    `passenger_count` Float64,
    `trip_distance` Float64,
    `RatecodeID` Float64,
    `store_and_fwd_flag` String,
    `PULocationID` Int64,
    `DOLocationID` Int64,
    `payment_type` Int64,
    `fare_amount` Float64,
    `extra` Float64,
    `mta_tax` Float64,
    `tip_amount` Float64,
    `tolls_amount` Float64,
    `improvement_surcharge` Float64,
    `total_amount` Float64,
    `congestion_surcharge` Float64,
    `airport_fee` Float64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(tpep_pickup_datetime)
ORDER BY (VendorID, tpep_pickup_datetime, PULocationID, DOLocationID);
```

Em seguida, carregue os dados da tabela do catálogo do Lakekeeper por meio de um `INSERT INTO SELECT`:

```sql theme={null}
INSERT INTO taxis 
SELECT * FROM demo.`default.taxis`;
```
