如何防止Glue读取S3文件夹下所有文件的技术问询
解决方案
共有三种不同场景的实现方式,无需修改原有Glue表的Location配置即可实现仅读取单个目标文件:
方案1:最小代码改动的文件名过滤方案
读取目录元数据后通过Spark内置函数筛选目标文件,实际执行时Spark会跳过非目标文件的内容加载,仅扫描并读取目标文件数据:
from pyspark.sql.functions import input_file_name gluedb = "srcgluedb" gluetbl = "gluesrctable" # 替换为你需要读取的目标文件完整S3路径 target_file_path = "s3://<你的桶名>/<文件夹路径>/<目标文件名.后缀>" dfRead=glue_context.create_dynamic_frame.from_catalog(database=gluedb, table_name=gluetbl) df = dfRead.toDF() # 仅保留目标文件的数据 df_single_file = df.where(input_file_name() == target_file_path)
小提示:如果不想写完整S3路径,也可以用
df.where(input_file_name().endswith("<目标文件名.后缀>"))做后缀模糊匹配,适配路径前缀变动的场景。
方案2:直接指定单个文件路径读取,复用表Schema
如果需要完全跳过目录下其他文件的元数据扫描,可以主动拉取Glue表的Schema配置,直接读取目标文件:
gluedb = "srcgluedb" gluetbl = "gluesrctable" target_file_path = "s3://<你的桶名>/<文件夹路径>/<目标文件名.后缀>" # 获取Glue表的元配置(包含Schema、文件格式、SerDe等参数) table = glue_context._ssb.glue.get_table(DatabaseName=gluedb, Name=gluetbl) storage_config = table['Table']['StorageDescriptor'] # 直接读取单个文件,复用原有表的所有格式配置 df = glue_context.spark_session.read.format(storage_config['InputFormat'])\ .schema(storage_config['Columns'])\ .load(target_file_path)
长期优化方案(高频单文件读取场景)
如果业务上经常需要按单个文件处理数据,可以将Glue表改造为按文件名分区,读取时直接走分区过滤性能最优:
- 给Glue表新增
file_name分区字段,原有存储Location保持不变 - 每次写入新文件时同步新增对应分区,分区值设为当前写入的文件名
- 后续读取时直接用谓词下推过滤分区,无需扫描其他文件的任何信息:
dfRead=glue_context.create_dynamic_frame.from_catalog( database=gluedb, table_name=gluetbl, push_down_predicate = "file_name='<目标文件名.后缀>'" )
内容的提问来源于stack exchange,提问作者iamaj
相关产品推荐
相关产品推荐

