⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
S3 API 支持

httpfs 扩展支持使用 S3 API 在对象存储服务器上读取/写入/文件模式匹配文件。S3 提供了一个标准的 API 来读写远程文件(而早于 S3 的普通 HTTP 服务器不提供通用的写入 API)。DuckDB 符合 S3 API,该 API 现在在行业存储提供商中很常见。

平台

httpfs 文件系统已通过 AWS S3MinioGoogle CloudlakeFS 的测试。其他实现 S3 API 的服务(例如 Cloudflare R2)也应该可用,但并非所有功能都可能受支持。

下表显示了每个 httpfs 功能所需的 S3 API 部分。

功能 所需的 S3 API 功能
公共文件读取 HTTP Range 请求
私有文件读取 密钥或会话令牌身份验证
文件模式匹配 ListObjectsV2
文件写入 分段上传

配置和身份验证

配置和验证 S3 端点的首选方法是使用密钥。有多个密钥提供程序可用。

要从已废弃的 S3 API 迁移,请使用具有配置文件的已定义密钥。请参阅“根据配置文件加载密钥”部分

config 提供程序

默认提供程序 config(即用户配置),允许通过手动提供密钥来访问 S3 存储桶。例如

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER config,
    KEY_ID 'AKIAIOSFODNN7EXAMPLE',
    SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    REGION 'us-east-1'
);

提示 如果您遇到 IO 错误(Connection error for HTTP HEAD),请通过 ENDPOINT 's3.your_region.amazonaws.com' 显式配置端点。

现在,要使用上述密钥进行查询,只需查询任何以 s3:// 为前缀的文件即可

SELECT *
FROM 's3://your-bucket/your_file.parquet';

credential_chain 提供者

credential_chain 提供程序允许使用 AWS SDK 提供的机制自动获取凭证。例如,要使用 AWS SDK 默认提供程序

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER credential_chain
);

同样,要使用上述密钥查询文件,只需查询任何以 s3:// 为前缀的文件即可。

DuckDB 还允许使用 CHAIN 关键字指定特定的链。这需要一个以分号分隔的提供程序列表(a;b;c),这些提供程序将按顺序尝试。例如

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER credential_chain,
    CHAIN 'env;config'
);

CHAIN 的可能值如下

credential_chain 提供程序还允许覆盖自动获取的配置。例如,要自动加载凭证,然后覆盖区域,请运行

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER credential_chain,
    CHAIN config,
    REGION 'eu-west-1'
);

根据配置文件加载密钥

要根据未从 AWS_PROFILE 环境变量定义为默认值或未根据 AWS SDK 优先级定义为默认配置文件的配置文件加载凭证,请运行

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER credential_chain,
    CHAIN config,
    PROFILE 'my_profile'
);

此方法等同于已废弃的 S3 APIload_aws_credentials('⟨my_profile⟩') 方法。

S3 密钥参数概述

下面是 configcredential_chain 提供程序都支持的参数的完整列表

名称 描述 密钥 类型 默认值
ENDPOINT 指定自定义 S3 端点 S3GCSR2 字符串 S3s3.amazonaws.com
KEY_ID 要使用的密钥 ID S3GCSR2 字符串 -
REGION 要进行身份验证的区域(应与要查询的存储桶的区域匹配) S3GCSR2 字符串 us-east-1
SECRET 要使用的密钥 S3GCSR2 字符串 -
SESSION_TOKEN 可选地,可以传递会话令牌以使用临时凭证 S3GCSR2 字符串 -
URL_COMPATIBILITY_MODE 当 URL 包含有问题字符时有帮助 S3GCSR2 布尔值 true
URL_STYLE vhostpath S3GCSR2 字符串 S3vhostR2GCSpath
USE_SSL 是否使用 HTTPS 或 HTTP S3GCSR2 布尔值 true
ACCOUNT_ID 用于生成端点 URL 的 R2 账户 ID R2 字符串 -
KMS_KEY_ID 用于 S3 服务器端加密的 AWS KMS(密钥管理服务)密钥 S3 字符串 -

平台特定的密钥类型

S3 密钥

httpfs 扩展支持使用 KMS_KEY_ID 选项在 S3 上通过 AWS 密钥管理服务 (KMS) 进行服务器端加密

CREATE OR REPLACE SECRET secret (
    TYPE s3,
    PROVIDER credential_chain,
    CHAIN config,
    REGION 'eu-west-1',
    KMS_KEY_ID 'arn:aws:kms:region:account_id:key/key_id',
    SCOPE 's3://bucket-sub-path'
);

R2 密钥

尽管 Cloudflare R2 使用常规的 S3 API,但 DuckDB 有一个特殊的密钥类型 R2,以使其配置更简单一些。

CREATE OR REPLACE SECRET secret (
    TYPE r2,
    KEY_ID 'AKIAIOSFODNN7EXAMPLE',
    SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    ACCOUNT_ID 'my_account_id'
);

请注意新增的 ACCOUNT_ID,它用于为您生成正确的端点 URL。另请注意,R2 密钥也可以使用 CONFIGcredential_chain 提供程序。然而,由于 DuckDB 内部使用 AWS 客户端,当使用 credential_chain 时,客户端将在标准 AWS 凭证位置(环境变量、凭证文件等)中搜索 AWS 凭证。因此,您的 R2 凭证必须以 AWS 环境变量(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)的形式提供,以使凭证链正常工作。最后,R2 密钥仅在 URL 以 r2:// 开头时可用,例如

SELECT *
FROM read_parquet('r2://some-file-that-uses-an-r2-secret.parquet');

GCS 密钥

尽管 DuckDB 使用 S3 API 访问 Google Cloud Storage,但 DuckDB 有一个特殊的密钥类型 GCS,以使其配置更简单一些。

CREATE OR REPLACE SECRET secret (
    TYPE gcs,
    KEY_ID 'my_hmac_access_id',
    SECRET 'my_hmac_secret_key'
);

重要提示KEY_IDSECRET 值必须是专为 Google Cloud Storage 互操作性生成的 HMAC 密钥。这些密钥与常规 GCP 服务账户密钥或访问令牌不同。您可以按照Google Cloud 关于管理 HMAC 密钥的文档创建 HMAC 密钥。

请注意,上述密钥将自动配置正确的 Google Cloud Storage 端点。另请注意,GCS 密钥也可以使用 CONFIGcredential_chain 提供程序。然而,由于 DuckDB 内部使用 AWS 客户端,当使用 credential_chain 时,客户端将在标准 AWS 凭证位置(环境变量、凭证文件等)中搜索 AWS 凭证。因此,您的 GCS HMAC 密钥必须以 AWS 环境变量(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)的形式提供,以使凭证链正常工作。最后,GCS 密钥仅在 URL 以 gcs://gs:// 开头时可用,例如

SELECT *
FROM read_parquet('gcs://some/file/that/uses/a/gcs/secret.parquet');

读取

现在,从 S3 读取文件就像这样简单

SELECT *
FROM 's3://your-bucket/filename.extension';

部分读取

httpfs 扩展支持从 S3 存储桶进行部分读取

读取多个文件

也可以处理多个文件,例如

SELECT *
FROM read_parquet([
    's3://your-bucket/filename-1.parquet',
    's3://your-bucket/filename-2.parquet'
]);

文件模式匹配

文件模式匹配是使用 ListObjectsV2 API 调用实现的,允许使用类似文件系统的 glob 模式来匹配多个文件,例如

SELECT *
FROM read_parquet('s3://your-bucket/*.parquet');

此查询匹配存储桶根目录中所有带有Parquet 扩展名的文件。

支持多种匹配功能,例如 * 匹配任意数量的任意字符,? 匹配任意单个字符,或 [0-9] 匹配指定范围内的单个字符。

SELECT count(*) FROM read_parquet('s3://your-bucket/folder*/100?/t[0-9].parquet');

使用 glob 时一个有用的功能是 filename 选项,它会添加一个名为 filename 的列,该列编码了特定行来自的文件。

SELECT *
FROM read_parquet('s3://your-bucket/*.parquet', filename = true);

例如,这可能会导致

column_a column_b 文件名
1 examplevalue1 s3://bucket-name/file1.parquet
2 examplevalue1 s3://bucket-name/file2.parquet

Hive 分区

DuckDB 还支持 Hive 分区方案,在使用 HTTP(S) 和 S3 端点时可用。

写入

写入 S3 使用分段上传 API。这使得 DuckDB 能够以高速稳定地上传文件。写入 S3 适用于 CSV 和 Parquet 格式。

COPY table_name TO 's3://your-bucket/filename.extension';

分区复制到 S3 也适用。

COPY table TO 's3://your-bucket/partitioned' (
    FORMAT parquet,
    PARTITION_BY (part_col_a, part_col_b)
);

系统会对现有文件/目录进行自动检查,目前这相当保守(并且在 S3 上会增加一些延迟)。要禁用此检查并强制写入,请添加 OVERWRITE_OR_IGNORE 标志。

COPY table TO 's3://your-bucket/partitioned' (
    FORMAT parquet,
    PARTITION_BY (part_col_a, part_col_b),
    OVERWRITE_OR_IGNORE true
);

写入文件的命名方案如下所示

s3://your-bucket/partitioned/part_col_a=val/part_col_b=val/data_thread_number.parquet

配置

S3 上传还有一些额外的配置选项,尽管默认值应足以满足大多数用例。

名称 描述
s3_uploader_max_parts_per_file 用于部分大小计算,请参阅AWS 文档
s3_uploader_max_filesize 用于部分大小计算,请参阅AWS 文档
s3_uploader_thread_limit 最大上传线程数