在AWS Lambda中读取S3存储桶XLSX文件时遇seek错误求助
解决AWS Lambda读取S3中XLSX文件的seek错误
问题现象
调用Lambda读取S3存储桶内的XLSX文件时触发UnsupportedOperation: seek错误,报错栈如下:
[ERROR] UnsupportedOperation: seek Traceback (most recent call last): File "/var/task/lambda_function.py", line 19, in lambda_handler df = pd.read_excel(xl_file['Body'], dtype_backend='pyarrow', header=[1,2]) File "/opt/python/pandas/io/excel/_base.py", line 495, in read_excel io = ExcelFile( File "/opt/python/pandas/io/excel/_base.py", line 1550, in __init__ ext = inspect_excel_format( File "/opt/python/pandas/io/excel/_base.py", line 1406, in inspect_excel_format stream.seek(0)
本地读取本地目录的XLSX文件时代码运行正常,但Lambda环境下读取S3文件失败。
问题原因
S3 get_object接口返回的xl_file['Body']是StreamingBody类型,这是单向流式对象,不支持seek操作。而pandas的read_excel方法在检测文件格式时需要调用seek(0)重置流位置,因此触发不支持操作的错误。
解决方案
将StreamingBody转换为支持seek操作的BytesIO对象,再传入pd.read_excel。修改后的代码如下:
import json import boto3 import io import pandas as pd s3Client = boto3.client('s3') def lambda_handler(event, context): bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] xl_file = s3Client.get_object(Bucket = bucket, Key = key) # 将流式对象转为可随机访问的BytesIO excel_data = io.BytesIO(xl_file['Body'].read()) df = pd.read_excel(excel_data, dtype_backend='pyarrow', header=[1,2]) # 后续业务逻辑...
补充说明
io.BytesIO会把S3流的内容全部加载到内存中,形成可随机访问的字节流,满足pandas对seek操作的需求。- 若XLSX文件体积过大,可能导致Lambda内存不足,此时需考虑提升Lambda内存配置或采用分块处理方案。
内容的提问来源于stack exchange,提问作者Kimbo
相关产品推荐
相关产品推荐

