【问题标题】:Cannot Upload Multiple Files to AWS S3 using Python Script and wildcards无法使用 Python 脚本和通配符将多个文件上传到 AWS S3
【发布时间】:2020-02-01 07:19:13
【问题描述】:

我对使用 python 和 AWS 比较陌生。

我正在尝试通过 python 脚本将具有特定格式的各种文件“通常”从我的本地 pc 移动到 S3 AWS 文件夹。我在脚本中实现通配符以一次捕获各种文件时遇到问题。我可以使用字符串 "data = open('file_example_here.csv', 'rb')" 一次移动一个文件,尽管我一直在调整我的 python 脚本以捕获所有文件(即 .csv 或所有 .json文件)。下面详细介绍了一组示例文件,因此,如果我想在脚本中使用通配符将所有 .json 文件移动到我的 s3 实例,我该如何调整我的脚本以处理该问题(如果可能)?

任何帮助将不胜感激,下面分享实现。


/home/user/folder1/c_log_1-10-19.csv
/home/user/folder1/c_log_2-10-19.csv
/home/user/folder1/c_log_3-10-19.csv
/home/user/folder1/c_log_4-10-19.csv
/home/user/folder1/c_log_5-10-19.csv
/home/user/folder1/c_log_6-10-19.csv

/home/user/folder1/h_log_1-11-18.json
/home/user/folder1/h_log_2-11-18.json
/home/user/folder1/h_log_3-11-18.json
/home/user/folder1/h_log_4-11-18.json
/home/user/folder1/h_log_5-11-18.json
/home/user/folder1/h_log_6-11-18.json

import boto3
from botocore.client import Config

ACCESS_KEY_ID = 'key_id_here'
ACCESS_SECRET_KEY = 'secret_key_here'
BUCKET_NAME = 'bucket_name_here'

data = open('test_file.csv', 'rb')

s3 = boto3.resource(
    's3',
    aws_access_key_id=ACCESS_KEY_ID,
    aws_secret_access_key=ACCESS_SECRET_KEY,
    config=Config(signature_version='s3v4')
)
s3.Bucket(BUCKET_NAME).put_object(Key='folder_test/folder_test_2/test_file.csv', Body=data)

print ("All_Done")


````````````````````````````````````````````````````
################################################
############## UPDATED CODE BELOW ############
################################################
import glob
import boto3
from botocore.client import Config

ACCESS_KEY_ID = 'some_key'
ACCESS_SECRET_KEY = 'some_key'
BUCKET_NAME = 'some_bucket'

#session = boto3.Session(profile_name='default')
s3 = boto3.resource(
    's3',
    aws_access_key_id=ACCESS_KEY_ID,
    aws_secret_access_key=ACCESS_SECRET_KEY,
    config=Config(signature_version='s3v4')
)

csv_files = glob.glob("/home/user/Desktop/*.csv")
#json_files = glob.glob("/home/user/folder1/h_log_*.json")

for filename in csv_files:
    print("Putting %s" % filename)
    s3.upload_file(filename, BUCKET_NAME, filename)

#for filename in json_files:
#    print("Putting %s" % filename)
#    s3.upload_file(filename, BUCKET_NAME, filename)

s3.Bucket(BUCKET_NAME).put_object(Key='folder1/folder1', Body=csv_files)

print("All_Done")

【问题讨论】:

    标签: python amazon-s3 aws-sdk boto3


    【解决方案1】:

    您可以使用像 Python 的 glob 模块这样简单的东西来查找与指定模式匹配的所有文件,如下例所示:

    #!/usr/bin/env python
    
    import glob
    import boto3
    import os
    
    BUCKET_NAME = 'MyBucket'
    FOLDER_NAME = 'folder1/folder1'
    
    session = boto3.Session(profile_name='default')
    s3 = session.client('s3')
    
    csv_files = glob.glob("/home/user/folder1/c_log_*.csv")
    json_files = glob.glob("/home/user/folder1/h_log_*.json")
    
    for filename in csv_files:
        key = "%s/%s" % (FOLDER_NAME, os.path.basename(filename))
        print("Putting %s as %s" % (filename,key))
        s3.upload_file(filename, BUCKET_NAME, key)
    
    for filename in json_files:
        key = "%s/%s" % (FOLDER_NAME, os.path.basename(filename))
        print("Putting %s as %s" % (filename,key))
        s3.upload_file(filename, BUCKET_NAME, key)
    
    print("All_Done")
    

    以上代码假定您已安装 AWS CLI,并在默认配置文件下配置了访问密钥。如果没有,可以使用authenticating with boto3的各种方法。

    可能有一种更 Pythonic 的方式可以做到这一点,但这个简单的脚本可以工作。

    【讨论】:

    • 感谢您的回复,我将上面的代码更新到了原来的下方。虽然有一种方法可以构造代码以仍然维护将代码放在 s3 上的特定文件夹中的字符串(即 s3.Bucket(BUCKET_NAME).put_object(Key='folder1/folder1', Body=csv_files)。另外,我在字符串( s3.upload_file(filename, BUCKET_NAME, filename ) >> 上收到错误消息(attributeerror: 's3.serviceresource' object has no attribute 'upload_file) ?? 你可以在@Ashaman 之前完成它吗?主销?
    • @bobparker,是的,upload_file 调用的第三个参数是可以包含文件夹名称的对象键名称。您是否只想提取文件名(例如 c_log_1-10-19.csv)并放入特定文件夹(文件夹 1/文件夹 1)?如果是这样,我已经修改了上面的代码。
    • @bobparker,至于您遇到的错误,请注意在我的代码中,我使用的是 boto3.Session,而您使用的是 boto3.resource。这可能是错误的原因。您可以改用 Session 还是出于特定原因必须使用资源?
    • @bobparker 看起来使用资源 API 比使用客户端 API 更好。如果您愿意,我将在今晚晚些时候翻译代码以使用资源而不是客户端。让我知道这是否不必要。
    • 嘿,再次感谢,我现在可以将 .csv 文件传递​​给 s3 实例,尽管我现在在将它们放入存储桶中的特定文件夹时遇到了问题。这有效 >>>> s3.upload_file(filename, BUCKET_NAME, filename) 这不是 s3.upload_file(filename, BUCKET_NAME, 'folder1/') @Ashaman Kingpin
    【解决方案2】:

    查看 glob 模块 (https://docs.python.org/3/library/glob.html)。

    import glob
    csv_files = glob.glob('/home/user/folder_1/*.csv')
    json_files = glob.glob('/home/user/folder_1/*.json')
    

    然后遍历这些列表并照常上传。

    此外,无需从文件中读取数据。只需在存储桶上使用 upload_file 方法:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Bucket.upload_file

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-16
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 2019-10-31
      • 2016-10-17
      • 2013-04-14
      • 2019-04-13
      相关资源
      最近更新 更多