在AWS Lambda中用DuckDB直接访问S3 Parquet文件失败排查
问题:DuckDB在AWS Lambda中直接访问S3 Parquet文件报HTTP 400错误
我在AWS S3中存储了一个Parquet文件,路径为s3://bucket/file.parquet,并在AWS Lambda中编写了如下函数尝试通过DuckDB直接访问该文件:
import os def lambda_handler(event, context): import duckdb con = duckdb.connect(database=':memory:', read_only=False) home_directory = "/tmp/duckdb/" if not os.path.exists(home_directory): os.mkdir(home_directory) con.query("SET home_directory='/tmp/duckdb/';") con.query("INSTALL 'httpfs';") con.query("LOAD 'httpfs';") con.query("SET s3_access_key_id='xxx';") con.query("SET s3_secret_access_key='xxx;") con.query("SET s3_region='us-east-1';") sql = "select * from read_parquet('s3://bucket/file.parquet') limit 5;" data = con.execute(sql).fetchall() print(data)
运行后出现以下错误:
{ "errorMessage": "HTTP Error: HTTP GET error on 's3://bucket/file.parquet' (HTTP 400)", "errorType": "HTTPException", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 140, in lambda_handler\n data = con.execute(sql).fetchall()\n" ] }
将S3路径替换为HTTPS签名URL,或通过boto3把文件下载到Lambda容器后访问均正常。根据DuckDB文档,直接传入S3路径是支持的,请问为何会失败?
原因分析与解决方案
1. 凭证配置语法错误
原代码中SET s3_secret_access_key='xxx;语句末尾缺少闭合的单引号,导致DuckDB无法正确解析S3密钥,进而生成格式错误的请求,触发HTTP 400错误。这是最直接的问题。
2. 硬编码密钥的风险与替代方案
即使修复引号,硬编码密钥也存在泄露风险。在Lambda环境中,更推荐使用IAM执行角色授权:
- 给Lambda的执行角色添加包含
s3:GetObject权限的策略,目标资源指定为s3://bucket/file.parquet或整个桶。 - DuckDB的HTTPFS扩展可以自动获取Lambda的IAM角色临时凭证,无需手动设置
s3_access_key_id和s3_secret_access_key。
3. 修正后的示例代码
import os import duckdb def lambda_handler(event, context): con = duckdb.connect(database=':memory:', read_only=False) home_directory = "/tmp/duckdb/" if not os.path.exists(home_directory): os.mkdir(home_directory) con.query(f"SET home_directory='{home_directory}';") con.query("INSTALL 'httpfs';") con.query("LOAD 'httpfs';") # 仅配置区域,依赖Lambda执行角色权限 con.query("SET s3_region='us-east-1';") sql = "select * from read_parquet('s3://bucket/file.parquet') limit 5;" data = con.execute(sql).fetchall() print(data)
4. 额外检查点
- 确认S3桶的区域与代码中设置的
s3_region一致,区域不匹配也可能导致请求错误。 - 检查S3对象的权限设置,确保执行角色或配置的密钥拥有该对象的读取权限。
内容的提问来源于stack exchange,提问作者pass-by-ref
相关产品推荐
相关产品推荐

