带参POST请求调用AWS Lambda查询EC2 MySQL失败求助
问题排查与修复方案
核心问题分析
- Event结构不匹配:AWS控制台测试时,参数直接放在
event根节点,但API Gateway转发POST请求时,参数会被封装在event['body']字段中,且是JSON字符串格式,而非直接的JSON对象。代码直接尝试event['hotel_id']会抛出KeyError。 - 数据库连接生命周期错误:将数据库连接放在Lambda handler外部,容器复用过程中会因MySQL主动断开空闲连接导致后续请求失败。
- 异常处理逻辑失效:异常分支中尝试访问
responseBody.statusCode,但responseBody初始值是空字符串,会触发新的AttributeError;同时异常返回的body没有实际错误信息,无法定位问题。
修复后的代码
import pymysql import json # Configuration Values endpoint = 'secret' username = 'secret' password = 'secret' database_name = 'secret' def lambda_handler(event, context): print("EVENT:", event) responseBody = "" try: # 解析请求参数:兼容API Gateway和控制台测试场景 if 'body' in event and event['body']: try: event_body = json.loads(event['body']) hotel_id = event_body.get('hotel_id') if not hotel_id: raise ValueError("hotel_id参数缺失") except json.JSONDecodeError: raise ValueError("请求body不是合法的JSON格式") else: hotel_id = event.get('hotel_id') if not hotel_id: raise ValueError("hotel_id参数缺失") # 在handler内部创建数据库连接,避免容器复用导致连接失效 connection = pymysql.connect( host=endpoint, user=username, passwd=password, db=database_name, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor ) query = 'SELECT * FROM hotelxml WHERE hotel_id = %s' cursor = connection.cursor() cursor.execute(query, (hotel_id,)) rows = cursor.fetchall() for row in rows: print(row) print("\n") responseBody = json.dumps(rows, separators=(',', ':')) response = { "isBase64Encoded": False, 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, "body": responseBody } except Exception as e: # 返回明确的错误信息,便于排查 error_msg = json.dumps({"error": str(e)}) response = { "isBase64Encoded": False, 'statusCode': 400, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, "body": error_msg } print("exception occured: {}".format(e)) finally: # 确保数据库连接关闭,避免资源泄漏 if 'connection' in locals(): connection.close() return response
关键修复点说明
- 参数解析逻辑:
- 优先解析API Gateway传入的
event['body'](JSON字符串),提取hotel_id - 兼容控制台测试场景,直接从
event根节点获取参数 - 增加参数校验,避免缺失
hotel_id的非法请求
- 优先解析API Gateway传入的
- 数据库连接优化:
- 将连接创建移到handler内部,每次请求建立新连接(可根据业务需求引入连接池优化性能)
- 在finally块中强制关闭连接,防止资源泄漏
- 异常处理修复:
- 捕获所有异常,返回包含错误详情的JSON响应
- 设置合理的状态码(400表示客户端错误),替换无效的
responseBody.statusCode
- 细节修正:
- 修复换行符错误:将
print("/n")改为print("\n") - 移除未使用的
requests库、url和headers变量,精简代码
- 修复换行符错误:将
测试建议
- Postman发送POST请求时,选择
raw -> JSON格式,传入{"hotel_id": "10717"} - 查看CloudWatch日志中的
EVENT输出,确认API Gateway传递的参数结构是否符合预期 - 若遇到跨域问题,确保API Gateway控制台已配置正确的CORS规则(代码返回的
Access-Control-Allow-Origin: *需配合网关层面配置)
内容的提问来源于stack exchange,提问作者Seb St Johnston
相关产品推荐
相关产品推荐

