You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带参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

关键修复点说明

  1. 参数解析逻辑:
    • 优先解析API Gateway传入的event['body'](JSON字符串),提取hotel_id
    • 兼容控制台测试场景,直接从event根节点获取参数
    • 增加参数校验,避免缺失hotel_id的非法请求
  2. 数据库连接优化:
    • 将连接创建移到handler内部,每次请求建立新连接(可根据业务需求引入连接池优化性能)
    • 在finally块中强制关闭连接,防止资源泄漏
  3. 异常处理修复:
    • 捕获所有异常,返回包含错误详情的JSON响应
    • 设置合理的状态码(400表示客户端错误),替换无效的responseBody.statusCode
  4. 细节修正:
    • 修复换行符错误:将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:41:05