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

> En esta guía, le mostraremos cómo consultar sus datos con ClickHouse y el catálogo Iceberg de 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>
            Funcionalidad experimental
        </a>;
};

<ExperimentalBadge />

<Note>
  La integración con el catálogo de SeaweedFS solo funciona con tablas Iceberg.
</Note>

ClickHouse admite la integración con varios catálogos (Unity, Glue, REST, Polaris, etc.). Esta guía le mostrará cómo consultar sus datos con ClickHouse y el catálogo [SeaweedFS](https://github.com/seaweedfs/seaweedfs).

SeaweedFS es un almacén distribuido de archivos y objetos de código abierto con una puerta de enlace compatible con S3. Sus S3 Table Buckets proporcionan ambas partes de una implementación de Iceberg: el catálogo REST de Iceberg integrado sirve los metadatos de las tablas y el bucket de tablas almacena los datos de las tablas como archivos Parquet a través del mismo endpoint de S3:

* **Servicio único**: los metadatos del catálogo y los datos Parquet se sirven desde un único proceso, sin una base de datos de metadatos independiente
* Cumplimiento de la especificación de catálogo REST de Iceberg mediante la **API REST**
* **Mantenimiento en el servidor**: compactación automática de archivos Parquet y expiración de snapshots, sin un servicio de mantenimiento externo

<Note>
  Dado que esta funcionalidad es experimental, debe habilitarla con:
  `SET allow_experimental_database_iceberg = 1;`
</Note>

<div id="local-development-setup">
  ## Configuración para desarrollo local
</div>

Para el desarrollo y las pruebas locales, puede ejecutar SeaweedFS y ClickHouse con Docker Compose. Este enfoque es ideal para aprender, crear prototipos y trabajar en entornos de desarrollo.

<div id="local-prerequisites">
  ### Requisitos previos
</div>

1. **Docker y Docker Compose**: asegúrese de que Docker esté instalado y en ejecución
2. **Versiones**: SeaweedFS 4.42 o posterior; ClickHouse 26.8 o posterior (las versiones desde la 25.8 pueden leer e insertar, pero para crear tablas mediante el catálogo se requiere la 26.8)
3. **Python con PyIceberg** (opcional): se utiliza a continuación para inicializar datos de muestra

<div id="setting-up-local-seaweedfs-catalog">
  ### Configuración del catálogo local de SeaweedFS
</div>

**Paso 1:** Cree una carpeta nueva para ejecutar el ejemplo y, a continuación, cree un archivo `s3config.json` con las credenciales de la puerta de enlace de S3 y del catálogo:

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

**Paso 2:** Cree un archivo `docker-compose.yml` con la siguiente configuración:

```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
```

El comando `mini` inicia toda la pila de SeaweedFS en un único contenedor. El indicador `-tableBucket=analytics` crea de antemano un bucket de S3 Tables llamado `analytics`, que sirve como warehouse de Iceberg.

**Paso 3:** Ejecute el siguiente comando para iniciar los servicios:

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

<div id="seeding-sample-data">
  ### Carga de datos de ejemplo
</div>

El catálogo está inicialmente vacío. Cree una tabla y añada algunas filas con 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">
  ### Conexión al catálogo local de SeaweedFS
</div>

Conéctese a su contenedor de ClickHouse:

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

A continuación, cree la conexión de base de datos con el catálogo de 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'
```

Los argumentos del motor contienen las credenciales de S3 que ClickHouse utiliza para leer los datos de la tabla, mientras que `catalog_credential` y `oauth_server_uri` autentican en el propio catálogo mediante el flujo OAuth2 de credenciales de cliente. SeaweedFS acepta la misma clave de acceso y clave secreta para ambos.

<div id="querying-seaweedfs-catalog-tables-using-clickhouse">
  ## Consultar tablas de catálogo de SeaweedFS con ClickHouse
</div>

Ahora que la conexión está establecida, puede empezar a realizar consultas a través del catálogo de SeaweedFS. Por ejemplo:

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

SHOW TABLES;
```

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

<Info>
  **Se requieren comillas invertidas**

  Las comillas invertidas son necesarias porque ClickHouse no admite más de un espacio de nombres.
</Info>

Para consultar una tabla:

```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">
  ## Crear tablas y escribir datos desde ClickHouse
</div>

También puede crear tablas en el catálogo de SeaweedFS y escribir directamente en ellas desde 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 │
└────┴────────────┘
```

La cláusula del motor `IcebergS3` especifica la ruta de almacenamiento de la nueva tabla, y `write_full_path_in_iceberg_metadata` hace que ClickHouse registre la ubicación completa de la tabla en el catálogo.

<Note>
  La creación de tablas mediante un catálogo requiere ClickHouse 26.8 o una versión posterior. Las versiones 26.4 a 26.7 escriben los archivos de la tabla antes de registrar el espacio de nombres, algo que SeaweedFS rechaza salvo que el espacio de nombres ya exista en el catálogo; las versiones anteriores a la 26.4 parecen funcionar correctamente, pero los archivos de la tabla se escriben en el almacenamiento de objetos sin registrarse en el catálogo.
</Note>

Cuando ClickHouse confirma una inserción, el catálogo de SeaweedFS corrige los metadatos que el writer experimental todavía no genera: completa los ID de campo que faltan en los manifests, reescribe como ubicaciones absolutas las rutas de archivo relativas al bucket y asigna a la tabla una correspondencia de nombres predeterminada. Los readers estrictos, como PyIceberg y Spark, pueden entonces leer las filas escritas por ClickHouse. Esto requiere SeaweedFS 4.42 o una versión posterior.

<div id="loading-data-from-your-data-lake-into-clickhouse">
  ## Carga de datos desde su lago de datos en ClickHouse
</div>

Si necesita cargar datos del catálogo de SeaweedFS en ClickHouse, primero cree una tabla local de ClickHouse:

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

A continuación, cargue los datos de la tabla de catálogo de SeaweedFS mediante un `INSERT INTO SELECT`:

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