AWS Glue解压Zip/Gzip文件:S3数据处理与数据目录创建问询
嘿,我来帮你梳理下AWS Glue处理压缩文件的方案,尤其是你提到的每日上传Gzip(应该是tar.gz?毕竟Gzip本身只能压缩单个文件,多个CSV的话通常是tar包再Gzip)包含10个同Schema CSV的场景:
一、Gzip/tar.gz文件:Glue原生支持,无需复杂操作
AWS Glue对Gzip格式有原生支持,不管是数据爬虫还是ETL脚本都能轻松处理,分两种情况说:
1. 直接用Glue爬虫生成数据目录
你的场景里,Gzip解压后是10个同Schema的CSV,Glue爬虫完全可以自动识别并生成统一的表结构到数据目录,步骤如下:
- 把每日的Gzip文件都放在S3的同一个前缀下,比如
s3://your-bucket/daily-uploads/ - 创建爬虫时,选择S3作为数据源,勾选「压缩文件」选项(默认是开启的,但建议确认)
- 爬虫会自动解压Gzip/tar.gz,读取里面的所有CSV,合并它们的Schema(因为你说Schema完全一致,所以会生成统一的表结构),最后把表同步到Glue数据目录里。完全不需要手动提前解压!
如果爬虫偶尔识别有问题,比如文件命名太乱,你可以在爬虫配置里添加「排除模式」或者调整「分类器优先级」,确保CSV分类器优先触发。
2. 在Python ETL脚本中直接处理(解压+加载)
如果你需要在ETL流程中自定义解压逻辑,或者直接处理数据,Glue的Python环境已经自带了所有必要的库,不需要额外安装。这里给你两个实用的脚本片段:
片段1:自动读取Gzip文件(无需手动解压)
Glue的DynamicFrame和Spark可以自动处理Gzip压缩,直接读取里面的CSV,非常省心:
from awsglue.context import GlueContext from pyspark.context import SparkContext # 初始化Glue上下文 sc = SparkContext() glueContext = GlueContext(sc) # 直接读取S3上的所有Gzip文件,自动解压并加载 daily_data = glueContext.create_dynamic_frame.from_options( connection_type="s3", connection_options={"paths": ["s3://your-bucket/daily-uploads/*.gz"]}, format="csv", format_options={"withHeader": True, "separator": ","} # 根据你的CSV格式调整 ) # 转换成Spark DataFrame做后续处理 df = daily_data.toDF() df.show(5) # 预览数据
片段2:手动解压tar.gz并写入S3(如果需要保留解压后的文件)
如果需要把解压后的CSV单独存到S3供其他系统使用,可以用tarfile和boto3实现:
import boto3 import tarfile from io import BytesIO from awsglue.utils import getResolvedOptions import sys # 获取作业参数(比如从Glue作业传递的源路径、目标路径) args = getResolvedOptions(sys.argv, ['S3_SOURCE', 'S3_DEST']) s3_client = boto3.client('s3') # 解析S3路径 bucket = args['S3_SOURCE'].split('/')[2] object_key = '/'.join(args['S3_SOURCE'].split('/')[3:]) # 读取S3上的tar.gz文件 response = s3_client.get_object(Bucket=bucket, Key=object_key) tar_content = BytesIO(response['Body'].read()) # 解压并逐个写入S3 with tarfile.open(fileobj=tar_content, mode='r:gz') as tar: for member in tar.getmembers(): if member.isfile() and member.name.endswith('.csv'): csv_data = tar.extractfile(member).read() # 写入到目标路径 s3_client.put_object( Bucket=bucket, Key=f"{args['S3_DEST']}/{member.name}", Body=csv_data )
二、Zip文件处理:手动解压脚本实现
Glue没有原生支持Zip文件的自动解析,所以需要在ETL脚本里用Python标准库zipfile处理,示例如下:
import zipfile import boto3 from io import BytesIO s3_client = boto3.client('s3') bucket_name = "your-bucket" zip_file_key = "path/to/your/file.zip" unzip_dest_prefix = "unzipped-csvs/" # 读取Zip文件 response = s3_client.get_object(Bucket=bucket_name, Key=zip_file_key) zip_buffer = BytesIO(response['Body'].read()) # 解压并写入S3 with zipfile.ZipFile(zip_buffer, 'r') as zip_ref: for file_info in zip_ref.infolist(): if not file_info.is_dir() and file_info.filename.endswith('.csv'): file_data = zip_ref.read(file_info.filename) s3_client.put_object( Bucket=bucket_name, Key=f"{unzip_dest_prefix}{file_info.filename}", Body=file_data )
解压完成后,就可以用Glue爬虫去爬unzip_dest_prefix下的文件,创建数据目录了。
三、针对你场景的最佳建议
结合你的需求(每日Gzip→解压→爬虫建Schema→ETL),最推荐方案一:直接用Glue爬虫+DynamicFrame读取:
- 爬虫自动识别Gzip里的CSV,生成统一Schema到数据目录,省去手动解压步骤
- ETL脚本直接用
create_dynamic_frame.from_options读取压缩文件,自动解压加载,流程更高效 - 如果需要保留解压后的文件,再考虑用脚本先解压,然后爬解压后的目录
另外,Glue的Python运行环境已经预装了gzip、tarfile、zipfile、boto3等所有需要的库,直接调用就行,不用额外安装依赖。
内容的提问来源于stack exchange,提问作者Yuva

