DuckDB默认不支持S3协议,直接query s3://路径会因当作本地文件查找而报“IO Error: No files found”;必须安装duckdb[all]、启用httpfs扩展、正确配置S3凭证与region。

为什么直接用 duckdb.query() 会报错“IO Error: No files found”
因为 DuckDB 默认不支持 S3 协议,即使你传入 s3://bucket/key.parquet 这样的路径,它也会当成本地文件去查,自然找不到。必须显式启用 S3 支持并配置凭证——这不是可选步骤,是硬性前提。
实操建议:
- 安装带 Arrow + S3 支持的 DuckDB:运行
pip install duckdb[all](不是pip install duckdb),否则install_extension('httpfs')会失败 - 调用前必须先
install_extension('httpfs')和load_extension('httpfs'),顺序不能反,缺一不可 - 凭据优先走环境变量:
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_REGION;临时测试可用set_s3_config(),但生产环境别硬编码密钥
如何在查询中正确拼写 S3 路径和通配符
DuckDB 的 S3 路径解析很严格:协议必须小写 s3://,桶名不能带 https:// 或 s3.amazonaws.com 前缀,且通配符只支持 *(不支持 ** 或 ?)。
常见错误现象:
-
SELECT * FROM 's3://my-bucket/data/*.parquet'→ 正确 -
SELECT * FROM 's3://my-bucket/data/**/*.parquet'→ 报错,DuckDB 不递归匹配子目录 -
SELECT * FROM 'https://my-bucket.s3.us-east-1.amazonaws.com/data/part-0.parquet'→ 失败,必须用s3:// -
SELECT * FROM 's3://my-bucket/data/part-*.parquet' WHERE x > 10→ 可以,谓词下推有效,但前提是 Parquet 文件有统计信息
性能关键:要不要显式设置 SET s3_region='us-east-1'
要。如果不设,DuckDB 会尝试用虚拟托管式地址(https://bucket.s3.amazonaws.com)发起请求,而多数非 us-east-1 区域会返回 301 重定向,导致额外 RTT 和潜在认证失败。
实操建议:
- 始终在连接后立即执行
con.execute("SET s3_region='your-region'"),比如us-west-2、cn-north-1 - 如果用的是 IAM Role(如 EC2 实例角色),无需提供密钥,但
s3_region仍必须显式设置 - 对跨区域访问(如东京 bucket 从法兰克福查),延迟明显升高,尽量让 DuckDB 运行地与 S3 桶同区域
遇到 “HTTP HEAD failed” 或 “SignatureDoesNotMatch” 怎么快速定位
这类错误几乎全是认证或网络层问题,跟 SQL 本身无关。DuckDB 不会把原始 HTTP 错误细节透出,得靠前置检查缩小范围。
排查步骤:
- 用
aws s3 ls s3://bucket/path/确认能列文件,排除权限/网络问题 - 检查
AWS_REGION是否和桶实际区域一致(注意:不是你 AWS CLI 配置的默认 region) - 若用临时凭证(STS),确认
AWS_SESSION_TOKEN已导出,且未过期 - 若用 MinIO 或其他兼容 S3 的服务,需额外调用
set_s3_config('endpoint', 'minio:9000')和set_s3_config('url_style', 'path')
真正麻烦的不是语法,是 DuckDB 对 S3 错误的静默处理——它把底层 HTTP 异常吞掉后只抛泛化的 IO Error,所以验证必须在 DuckDB 外完成。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











