PySpark删除Amazon S3文件夹内文件异常:误删文件夹求助
解决方案
方法一:修正Boto3代码
S3里的“文件夹”本质是对象key的前缀,并非真实实体。如果要保留ongoing的显示,要么确保有一个key为build/subdomains/sim/users/ongoing/的空对象,要么删除文件后创建这个空对象。
修正后的代码如下:
import boto3 s3 = boto3.resource('s3') bucket = s3.Bucket('sales') # 前缀加上末尾斜杠,确保只匹配该文件夹下的对象 prefix = "build/subdomains/sim/users/ongoing/" # 批量收集要删除的对象(排除文件夹本身的空对象,如果存在) objects_to_delete = [] for obj in bucket.objects.filter(Prefix=prefix): # 只删除文件夹下的文件,不删除文件夹对应的空对象 if obj.key != prefix: objects_to_delete.append({'Key': obj.key}) # 批量删除(单次最多删1000个,超过的话需要分批) if objects_to_delete: bucket.delete_objects(Delete={'Objects': objects_to_delete}) # 如果需要确保文件夹存在,创建一个空对象(如果原本没有的话) bucket.put_object(Key=prefix, Body=b'')
说明:
- 前缀加斜杠后,只会匹配
ongoing/下的所有对象,不会误匹配其他前缀相似的对象。 - 批量删除比逐个删除更高效,避免多次API调用。
- 最后创建空对象可以保证S3控制台中依然显示
ongoing文件夹。
方法二:用PySpark实现
如果你需要用PySpark来操作,可以通过调用Hadoop的FileSystem API来完成:
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("DeleteS3Files").getOrCreate() # 获取Hadoop FileSystem实例 fs = spark._jvm.org.apache.hadoop.fs.FileSystem.get( spark._jvm.java.net.URI("s3a://sales"), spark._jsc.hadoopConfiguration() ) # 目标文件夹路径 folder_path = "s3a://sales/build/subdomains/sim/users/ongoing/" # 遍历文件夹下的所有文件并删除 status_list = fs.listStatus(spark._jvm.org.apache.hadoop.fs.Path(folder_path)) for status in status_list: if status.isFile(): fs.delete(status.getPath(), False) # 确保文件夹存在(如果原本不存在或被删除的话) if not fs.exists(spark._jvm.org.apache.hadoop.fs.Path(folder_path)): fs.mkdirs(spark._jvm.org.apache.hadoop.fs.Path(folder_path))
说明:
- 需要确保Spark环境配置了S3的访问凭证(比如通过
hadoopConfiguration设置fs.s3a.access.key和fs.s3a.secret.key)。 isFile()判断只删除文件,不删除子文件夹(如果需要删子文件夹可以调整逻辑)。- 最后调用
mkdirs可以保证文件夹在S3中显示存在。
内容的提问来源于stack exchange,提问作者user2280352
相关产品推荐
相关产品推荐

