如何在AWS Lambda中查询Amazon Athena关联的S3表存储大小
Athena查询关联S3表存储大小实现方案
你之前使用的SHOW TBLPROPERTIES语句本身在Athena中可正常执行,但该语句返回的表属性不包含对应S3路径的存储大小统计值,无法直接满足需求,可通过以下两种方案实现:
方案1:直接通过Athena系统表查询
直接查询information_schema.s3_files系统表统计指定表的总存储大小,查询语句如下:
SELECT SUM(size) AS total_size_bytes, SUM(size)/1024/1024 AS total_size_mb, SUM(size)/1024/1024/1024 AS total_size_gb FROM information_schema.s3_files WHERE table_schema = '替换为你的数据库名' AND table_name = '替换为你的表名';
- 该查询直接统计Athena表关联S3路径下的所有文件大小,不含S3多副本容量
- 仅支持Athena v2及以上版本,无需额外权限配置
方案2:Lambda联合Athena、S3 API实现(推荐大表/分区表使用)
如果需要统计分区表的分区级存储大小,或需要避免大表查询产生的Athena费用,可以通过Lambda先拉取表的S3关联路径,再调用S3接口统计容量,Python代码示例如下:
import boto3 import time athena_client = boto3.client('athena') s3_client = boto3.client('s3') # 配置项 DATABASE = '替换为你的数据库名' TABLE_NAME = '替换为你的表名' ATHENA_OUTPUT_LOCATION = 's3://替换为你的Athena查询结果存储桶路径/' def get_table_s3_path(): # 执行DESCRIBE查询获取表的S3存储路径 query = f"DESCRIBE FORMATTED {TABLE_NAME}" exec_resp = athena_client.start_query_execution( QueryString=query, QueryExecutionContext={'Database': DATABASE}, ResultConfiguration={'OutputLocation': ATHENA_OUTPUT_LOCATION} ) query_id = exec_resp['QueryExecutionId'] # 等待查询执行完成 while True: query_status = athena_client.get_query_execution(QueryExecutionId=query_id)['QueryExecution']['Status']['State'] if query_status in ['SUCCEEDED', 'FAILED', 'CANCELLED']: break time.sleep(0.5) if query_status != 'SUCCEEDED': raise Exception("查询表元信息失败") # 解析结果提取S3路径 query_result = athena_client.get_query_results(QueryExecutionId=query_id) for row in query_result['ResultSet']['Rows']: if row['Data'][0].get('VarCharValue') == 'Location:': s3_full_path = row['Data'][1].get('VarCharValue') bucket_name = s3_full_path.replace('s3://', '').split('/', 1)[0] prefix = s3_full_path.replace('s3://', '').split('/', 1)[1] return bucket_name, prefix def calculate_bucket_size(bucket, prefix): total_size = 0 paginator = s3_client.get_paginator('list_objects_v2') for page in paginator.paginate(Bucket=bucket, Prefix=prefix): if 'Contents' in page: for obj in page['Contents']: total_size += obj['Size'] return total_size if __name__ == "__main__": target_bucket, target_prefix = get_table_s3_path() total_bytes = calculate_bucket_size(target_bucket, target_prefix) print(f"表总存储容量:{total_bytes} 字节 / {total_bytes/1024/1024/1024:.2f} GB")
- 需要给Lambda执行角色配置Athena查询权限、对应S3桶的
list和get权限 - 适合TB级大表、分区表的存储统计,执行效率更高,无Athena查询费用
内容的提问来源于stack exchange,提问作者James bond
相关产品推荐
相关产品推荐

