ClickHouse 可通过 Horizon 提供的 Iceberg REST API (基于 Apache Polaris) 连接到 Snowflake Horizon Catalog。
借助 DataLakeCatalog 数据库引擎以及 catalog_type = 'horizon',您可以从 ClickHouse 读取和写入由 Snowflake 管理的 Iceberg 表。
Horizon 与 Snowflake Open Catalog / 自托管 Polaris 相关,但并不相同:
Open Catalog / Polaris (catalog_type = 'rest') |
Horizon (catalog_type = 'horizon') |
|
|---|---|---|
| 端点 | Open Catalog 或自托管 Polaris URI | https://<org>-<account>.snowflakecomputing.com/polaris/api/catalog |
| 仓库 | Polaris 目录 / 仓库名称 | Snowflake 数据库名称 (通常为大写) |
| 身份验证范围 | PRINCIPAL_ROLE:ALL (通常使用) |
session:role:<ROLE> |
| 凭据 | client_id:client_secret |
PAT 或密钥对 JWT (作为 catalog_credential;OAuth client_secret 不按 ':' 拆分) ,或 Bearer auth_header |
前置条件
- 拥有 Snowflake 托管的 Iceberg 表的 Snowflake 账户
- Horizon Iceberg REST 端点:
https://<organization>-<account>.snowflakecomputing.com/polaris/api/catalog - 对 Iceberg 表具有相应特权的 Snowflake 角色 (如需执行 INSERT,还应具有写入特权)
- 采用以下任一方式进行身份验证:
- 编程访问令牌 (PAT)
- 用于换取访问令牌的密钥对 JWT
- 外部 OAuth 访问令牌 (作为 Bearer
auth_header)
- 可供 ClickHouse 访问的对象存储 (建议使用下发的凭据)
- 支持 DataLakeCatalog Iceberg 的 ClickHouse
创建连接
选项 A:程序化访问令牌 (推荐)
SET allow_experimental_database_iceberg = 1;
CREATE DATABASE horizon_catalog
ENGINE = DataLakeCatalog('https://<org>-<account>.snowflakecomputing.com/polaris/api/catalog')
SETTINGS
catalog_type = 'horizon',
warehouse = 'ICEBERG_TEST_DB',
catalog_credential = '<PAT>',
auth_scope = 'session:role:DATA_ENGINEER',
oauth_server_uri = 'https://<org>-<account>.snowflakecomputing.com/polaris/api/catalog/v1/oauth/tokens',
vended_credentials = 1;warehouse 必须是 Snowflake 数据库名称 (而不是 Snowflake 虚拟仓库) 。
未加引号的 Snowflake 标识符均为大写。
选项 B:预先换取的 Bearer 访问令牌
CREATE DATABASE horizon_catalog
ENGINE = DataLakeCatalog('https://<org>-<account>.snowflakecomputing.com/polaris/api/catalog')
SETTINGS
catalog_type = 'horizon',
warehouse = 'ICEBERG_TEST_DB',
auth_header = 'Authorization: Bearer <ACCESS_TOKEN>',
vended_credentials = 1;查询 Iceberg 表
USE horizon_catalog;
SHOW TABLES;
SELECT count(*) FROM `PUBLIC.test_table`;
SHOW CREATE TABLE `PUBLIC.test_table`;写入路径
拥有 INSERT/UPDATE/DELETE 权限 (创建表时还需 CREATE ICEBERG TABLE 权限) 的角色 可以让 ClickHouse 通过同一目录写入:
-- Insert into an existing Snowflake-managed Iceberg table
INSERT INTO horizon_catalog.`PUBLIC.test_table`
SELECT
number AS id,
concat('name_', toString(number)) AS name
FROM numbers(100);
-- Create a new Iceberg table in the Horizon catalog (requires CREATE ICEBERG TABLE)
CREATE TABLE horizon_catalog.`PUBLIC.clickhouse_written`
(
id Int64,
name String
)
ENGINE = Iceberg;具体的 CREATE TABLE 语法取决于您所用版本中 ClickHouse Iceberg / DataLakeCatalog 对 REST 目录写入的支持;Snowflake 的权限问题会表现为目录 HTTP 错误。
加载到 MergeTree
CREATE TABLE my_clickhouse_table
(
id Int64,
name String
)
ENGINE = MergeTree
ORDER BY id;
INSERT INTO my_clickhouse_table
SELECT * FROM horizon_catalog.`PUBLIC.test_table`;