如何在Python的AWS Lambda Handler中实现GET及POST数据库操作
实现AWS Lambda的POST数据库插入操作方案
以下是修改后的代码,支持从POST请求中获取数据并插入数据库,同时保留原有的错误处理和连接管理逻辑:
import os import json import logging import mysql.connector from dotenv import load_dotenv # 初始化日志 logging.basicConfig(level=logging.INFO) def get_db_password(host): # 保留你原有的密码获取逻辑,比如从Secrets Manager获取 # 示例:return boto3.client('secretsmanager').get_secret_value(SecretId=host)['SecretString'] pass def execute_query(cursor, query, params=None): # 扩展执行函数支持参数化查询 if params: cursor.execute(query, params) else: cursor.execute(query) return cursor def close_connection(cursor, conn): # 保留原有的连接关闭逻辑 if cursor: cursor.close() if conn: conn.close() def lambda_handler(event, context): ''' Lambda处理函数,支持POST请求插入数据,GET请求查询数据(可选保留) ''' logging.info(f"Received request: {event}") try: # 加载环境变量 load_dotenv() # 创建数据库连接 conn = mysql.connector.connect( user=os.getenv('USER_NAME'), password=get_db_password(os.getenv('RDS_HOST')), host=os.getenv('RDS_HOST'), database=os.getenv('DB_NAME'), port=int(os.getenv('PORT')) # 端口转成整数,避免类型错误 ) cursor = conn.cursor(dictionary=True) # 使用字典游标,方便处理返回结果 # 获取请求方法 http_method = event.get('httpMethod', 'POST') if http_method == 'POST': # 解析POST请求的body数据 if not event.get('body'): return { 'statusCode': 400, 'body': json.dumps('Missing request body') } try: request_body = json.loads(event['body']) except json.JSONDecodeError: return { 'statusCode': 400, 'body': json.dumps('Invalid JSON in request body') } # 提取要插入的数据(根据你的表结构调整字段) # 示例:假设表table_1有字段name、email、created_at required_fields = ['name', 'email'] # 根据你的表结构修改 for field in required_fields: if field not in request_body: return { 'statusCode': 400, 'body': json.dumps(f'Missing required field: {field}') } # 构造参数化插入SQL,防止SQL注入 insert_query = """ INSERT INTO table_1 (name, email, created_at) VALUES (%s, %s, NOW()) """ insert_params = (request_body['name'], request_body['email']) # 执行插入并提交事务 execute_query(cursor, insert_query, insert_params) conn.commit() return { 'statusCode': 201, 'body': json.dumps(f"Successfully inserted {cursor.rowcount} record(s)") } elif http_method == 'GET': # 保留原有的查询逻辑(可选) query = "SELECT * from table_1;" execute_query(cursor, query) result = cursor.fetchall() if not result: return { 'statusCode': 404, 'body': json.dumps('No data returned from DB') } return { 'statusCode': 200, 'body': json.dumps(result) } else: return { 'statusCode': 405, 'body': json.dumps(f"Method {http_method} not allowed") } except Exception as error: logging.error(f"An unexpected error occurred: {str(error)}") # 如果事务未提交,回滚 if 'conn' in locals() and conn.is_connected(): conn.rollback() return { 'statusCode': 500, 'body': json.dumps(f'An error occurred: {str(error)}') } finally: close_connection(cursor, conn)
关键改动说明
- 请求方法处理:新增
httpMethod判断,区分POST插入和GET查询(GET逻辑可选保留) - POST数据解析:从
event['body']中解析JSON数据,补充格式校验和必填字段检查 - 参数化查询:使用
%s占位符构造插入SQL,彻底避免SQL注入风险 - 事务管理:插入操作后调用
conn.commit(),异常时执行conn.rollback()保证数据一致性 - 端口类型修正:将环境变量中的端口转为整数,避免连接数据库时的类型错误
- 字典游标:使用
dictionary=True创建游标,返回结果为字典格式,更易处理
必要配置注意事项
- IAM角色权限:确保Lambda执行角色拥有RDS访问权限(可配置细粒度权限而非全量权限),若使用Secrets Manager存储密码,还需添加Secrets Manager的读取权限
- 依赖包管理:Lambda默认不含
mysql-connector-python和python-dotenv,需将这些依赖打包成Lambda层,或与代码一起压缩上传 - API Gateway集成:若用API Gateway触发Lambda,需配置POST方法并开启Lambda代理集成,确保请求方法、body等数据能正确传递到Lambda的
event参数中 - 环境变量:确认Lambda的环境变量
USER_NAME、RDS_HOST、DB_NAME、PORT配置正确
内容的提问来源于stack exchange,提问作者user3521180
相关产品推荐
相关产品推荐

