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

# Lakekeeper カタログ

> このガイドでは、ClickHouse と 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>
            実験的な機能です。 <u><a href="/docs/docs/beta-and-experimental-features#experimental-features">詳細を見る。</a></u>
        </div>;
};

<ExperimentalBadge />

<Note>
  Lakekeeper カタログとのインテグレーションは、Iceberg テーブルでのみ利用できます。
  このインテグレーションは、AWS S3 とその他のクラウドストレージプロバイダーの両方に対応しています。
</Note>

ClickHouse は、複数のカタログ (Unity、Glue、REST、Polaris など) とのインテグレーションをサポートしています。このガイドでは、ClickHouse と [Lakekeeper](https://docs.lakekeeper.io/) カタログを使用してデータをクエリする手順を説明します。

Lakekeeper は、Apache Iceberg 向けのオープンソースの REST カタログ実装で、以下を提供します。

* 高いパフォーマンスと信頼性を実現する **Rust native** 実装
* Iceberg REST カタログ仕様に準拠した **REST API**
* S3-compatible ストレージと連携する **Cloud ストレージ** インテグレーション

<Note>
  この機能は実験段階のため、次を使用して有効にする必要があります。
  `SET allow_experimental_database_iceberg = 1;`
</Note>

<div id="local-development-setup">
  ## ローカル開発環境のセットアップ
</div>

ローカルでの開発やテストには、コンテナー化された Lakekeeper 構成を使用できます。この方法は、学習、プロトタイピング、開発環境に適しています。

<div id="local-prerequisites">
  ### 前提条件
</div>

1. **Docker と Docker Compose**: Docker がインストールされ、起動していることを確認してください
2. **サンプルセットアップ**: Lakekeeper の docker-compose セットアップを使用できます

<div id="setting-up-local-lakekeeper-catalog">
  ### ローカルの Lakekeeper カタログをセットアップする
</div>

Lakekeeper、PostgreSQL のメタデータバックエンド、オブジェクトストレージ用の MinIO を含む一式の環境が用意されている、公式の [Lakekeeper docker-compose setup](https://github.com/lakekeeper/lakekeeper/tree/main/examples/minimal) を利用できます。

**ステップ 1:** サンプルを実行するための新しいフォルダーを作成し、続けて次の設定内容で `docker-compose.yml` ファイルを作成します。

```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'  # Ensures root permissions
    ports:
      - "8123:8123"
      - "9000:9000"
    volumes:
      - clickhouse_data:/var/lib/clickhouse
      - ./clickhouse/data_import:/var/lib/clickhouse/data_import  # データセットフォルダをマウント
    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
```

**ステップ 2:** 次のコマンドを実行してサービスを起動します。

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

**ステップ 3:** すべてのサービスの準備が整うまで待ちます。ログは次のように確認できます:

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

<Note>
  Lakekeeper のセットアップでは、まず Iceberg テーブルにサンプルデータを読み込んでおく必要があります。ClickHouse 経由でそれらにクエリを実行する前に、環境側でテーブルが作成され、データが投入されていることを確認してください。利用可能なテーブルは、使用している docker-compose の構成とサンプルデータ読み込みスクリプトによって異なります。
</Note>

<div id="connecting-to-local-lakekeeper-catalog">
  ### ローカルの Lakekeeper カタログに接続する
</div>

ClickHouse コンテナーに接続します。

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

次に、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">
  ## ClickHouse を使用して Lakekeeper カタログのテーブルをクエリする
</div>

接続の設定が完了したので、Lakekeeper カタログ経由でクエリを実行できます。たとえば、次のとおりです。

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

SHOW TABLES;
```

構成にサンプルデータ (タクシーデータセットなど) が含まれている場合は、次のようなテーブルが表示されるはずです。

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

<Note>
  テーブルがまったく表示されない場合、通常は次のいずれかが原因です。

  1. 環境でまだサンプルテーブルが作成されていない
  2. Lakekeeper カタログサービスがまだ完全に初期化されていない
  3. サンプルデータの読み込み処理が完了していない

  テーブル作成の進行状況は、Spark のログで確認できます。

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

テーブルをクエリするには (利用可能な場合) :

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

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

<Info>
  **バッククォートが必要です**

  ClickHouse は複数のネームスペースをサポートしていないため、バッククォートが必要です。
</Info>

テーブルのDDLを確認するには:

```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">
  ## データレイクから ClickHouse にデータを読み込む
</div>

Lakekeeper カタログから ClickHouse にデータを読み込む必要がある場合は、まずローカルの 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);
```

次に、`INSERT INTO SELECT` を使って、Lakekeeper カタログのテーブルからデータを読み込みます。

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