【问题标题】:boto3 put_object with new key pythonboto3 put_object 与新键 python
【发布时间】:2025-11-15 11:15:01
【问题描述】:

我想使用 boto3 在 S3 中保存一个 csv 文件(“test.csv”)。 我的存储桶是“outputS3Bucket”,关键是“文件夹/newFolder”。 我想检查“newFolder”是否存在,如果不存在则创建它。

import boto3
client = boto3.client('s3')
s3 = boto3.resource('s3')
bucket = s3.Bucket("outputS3Bucket")

result = client.list_objects(Bucket='outputS3Bucket',Prefix="folder/newFolder")

if len(result)==0:
    key = bucket.new_key("folder/newFolder")
    newKey = key + "/" + "test.csv"

client.put_object(Bucket="outputS3Bucket", Key=newKey, Body=content)
# put_object path: 's3://outputS3Bucket/folder/newFolder/test.csv'

我有几个问题:

  1. 如果我没有写完整的键名(例如“folder/ne”)并且有一个“neaFo”文件夹,它仍然说它存在。
  2. key = bucket.new_key("文件夹/newFolder") AttributeError: 's3.Bucket' 对象没有属性 'new_key'

【问题讨论】:

  • 您的代码提到了bucket variable\object 用作​​key = bucket.new_key("folder/newFolder"),但是bucket 未在您的代码中的任何位置设置,您能否编辑您的问题以反映bucket 是什么?跨度>
  • @Eytan Avisror 抱歉,刚刚添加。

标签: python amazon-s3 boto3


【解决方案1】:

首先,根据 boto3 文档,最好使用新的 API 方法 - list_objects_v2() 而不是列出存储桶的对象。

我建议使用一个简单的布尔函数来检查一个文件夹是否存在(使您的代码更清晰,更具可读性)。 对于问题 1,您可以检查前缀是否以 '/' 字符结尾,如果不是则追加它,这将确保您正在寻找 EXACT 匹配而不是 以开头。

示例函数:

def bucket_folder_exists(client, bucket, path_prefix):
    # make path_prefix exact match and not path/to/folder*
    if list(path_prefix)[-1] is not '/':
        path_prefix += '/'

    # check if 'Contents' key exist in response dict - if it exist it indicate the folder exists, otherwise response will be None
    response = client.list_objects_v2(Bucket=bucket, Prefix=path_prefix).get('Contents')

    if response:
        return True
    return False

示例实现:

if bucket_folder_exists(client, 'outputS3Bucket', 'folder/newFolder'):
    pass # Do something if folder already exist
else:
    pass # Do something if folder does not exist

关于您的第二个问题,我添加了一条评论-您的代码似乎提到了用作key = bucket.new_key("folder/newFolder") 的存储桶变量\对象,但是您的代码中的任何地方都没有设置bucket,-> 根据对于您遇到的错误,它看起来像一个 s3.Bucket 对象,它没有定义 new_key 属性。

【讨论】:

  • 我添加到桶线。
  • 答案保持原样,Bucket 对象没有 new_key 属性。如果您只是将密钥作为字符串传递给其他方法,则它应该是局部变量中的字符串。