Lambda调用S3报NoSuchBucket错误排查及最终解决
Lambda调用外部API写入S3时的NoSuchBucket及空DataFrame问题解决
问题场景
- 本地Python 3.9.7环境运行正常,但Lambda(3.11/3.9.7版本)执行时始终抛出
An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation错误 - Lambda关联的IAM角色包含
AmazonS3FullAccess策略,目标S3 Bucket配置:开启Block Public Access、无自定义Bucket策略、Bucket Owner所有权、默认ACL,且与Lambda处于同一区域,Lambda已附加AWSSDKPandas-Python311层 - 尝试改用boto3直接写入S3,仍报相同错误;改用pandas处理数据后解决了Bucket错误,但又出现空DataFrame问题——CloudShell中用curl可正常获取API数据,但Lambda无法获取有效数据
错误根源与解决步骤
1. NoSuchBucket错误的核心原因
查看代码发现,调用外部股票数据API时错误使用了AWS Wrangler的s3.read_json方法,并传入s3://eodhistoricaldata.com/...格式的路径:
df = wr.s3.read_json( f's3://eodhistoricaldata.com/api/eod-bulk-last-day/{ex}?api_token=5f199920.009991&fmt=json&date={str(today)}', dtype={'code': str})
wr.s3.read_json是专为读取S3存储桶内JSON文件设计的工具,并非用于调用外部HTTP API。传入s3://eodhistoricaldata.com会触发工具尝试访问名为eodhistoricaldata.com的S3存储桶,而该桶并不存在,因此抛出NoSuchBucket错误。
修复方案
改用requests库直接调用外部API获取数据,再转换为DataFrame:
import requests import pandas as pd response = requests.get(f'https://eodhistoricaldata.com/api/eod-bulk-last-day/{ex}?api_token=5f199920.009991&fmt=json&date={str(today)}') df = pd.DataFrame(response.json())
替换后不再触发S3相关的List操作,Bucket错误即可解决。
2. 空DataFrame问题的原因
CloudShell能正常获取数据,但Lambda返回空DataFrame,根源在于时区差异:
- Lambda默认使用UTC时区,
date.today()获取的是UTC日期 - 目标API的“当日数据”按自身业务时区(如美国东部时间)更新,当UTC时间已过午夜,但API时区仍处于“非数据更新时段”(午夜到次日5点),此时API返回空数据,导致DataFrame为空。
修复方案
根据API使用的时区调整日期参数,例如API使用美国东部时间(UTC-5/UTC-4),则转换Lambda的日期计算逻辑:
from datetime import datetime import pytz # 定义API对应的时区 api_timezone = pytz.timezone('America/New_York') # 获取API时区下的当日日期 today = datetime.now(api_timezone).date()
使用对应时区的日期请求API,即可获取到有效数据。
总结
- 误用AWS Wrangler的S3操作方法调用外部API是
NoSuchBucket错误的核心原因,需改用HTTP请求库发起API调用 - Lambda默认UTC时区导致日期参数不符合API的时间范围,是空DataFrame问题的根源,需根据API时区调整日期计算逻辑
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

