【问题标题】:How can I upload a 'file' to S3 by creating a temp file, using AWS Lambda?如何使用 AWS Lambda 通过创建临时文件将“文件”上传到 S3?
【发布时间】:2017-05-26 06:56:03
【问题描述】:

我正在编写一个 lambda 函数,其目标是从 s3 下载一个 .json 文件,修改其内容,然后以不同的键重新上传到同一个存储桶。

所以在我的 s3 中,我有一个“云”存储桶 cloud/folder/foo.json

>>> foo.json
{
   "value1": "abc",
   "value2": "123"
}

我想下载它,相应地更改一些内容并将其重新上传到与 bar.json 相同的位置

我有第一部分的工作,因为它下载文件的内容并修改内容,但现在一切都是 python 字典对象。

import boto3
import json


def get_json():
    client = boto3.client('s3')
    response = client.get_object(Bucket='cloud', Key='folder/foo.json')
    data = response['Body'].read()
    bar = json.loads(data)
    bar["value-1"] = "do-re-mi"

    #TODO: implement uploading here   

def lambda_handler(event, context):
    get_json()
    return 'Hello from Lambda'

那么现在...

>>> bar
{
   "value1": "do-re-mi",
   "value2": "123"
}

bar 变量是正确的,但它是一个字典对象。我怎样才能以 bar.json 的形式直接上传到该存储桶? 我在这里看到了其他示例,但我并不热衷于将我的 AWS 密钥或访问密钥放在任何地方。我假设因为我使用的是 lambda,所以当我尝试执行以下操作时,我无法在机器上创建文件:

g = open('myfile.json', 'w')
g.write(json.dumps(bar, indent=4, sort_keys=True))
g.close()

with open('myfile.json', 'rb') as f:
    client.upload_fileobj(f, 'cloud', 'bar.json')

我得到一个“errorType”:“IOError”, "errorMessage": "[Errno 30] 只读文件系统:'myfile.json'"

任何建议将不胜感激。谢谢!

【问题讨论】:

  • 你试过StringIO或tempfile吗?您的实例有多少内存? Lambda 会让你写信给/tmp,如果你想把它写到 FS,请将它添加到你的路径中:thread in reddit
  • @monchitos82 非常感谢!没有意识到 lambda 支持文件系统。这对了解很有帮助
  • 很高兴为@user5494969 提供帮助,您的问题标题具有误导性,您可能需要解决这个问题以帮助处于相同情况的其他人。

标签: python amazon-s3 lambda boto3


【解决方案1】:

感谢 monchitos82,我了解到您可以在 lambda 中写入 /tmp。所以我所要做的就是将它添加到我的文件的开头并且它起作用了。

g = open('/tmp/myfile.json', 'w')
g.write(json.dumps(bar, indent=4, sort_keys=True))
g.close()

with open('/tmp/myfile.json', 'rb') as f:
    client.upload_fileobj(f, 'cloud', 'bar.json')

【讨论】:

  • 有500MB of space in /tmp。清理临时文件是一个好习惯,因为有时您会发现您的函数正在一个容器中运行,而该容器最近在过去几分钟内已经运行了相同的函数(“容器重用”),并且有了足够的时间,您可能会意外耗尽空间。并发调用不共享容器,但连续调用可以。不过,这不是安全问题——没有其他人会偶然发现您的文件,因为当容器由于不活动而最终被销毁时,它会被擦除。
  • @user5494969 能否请您发布包含临时文件创建的最终代码......
【解决方案2】:

显然你甚至不需要写一个临时文件; Key.open_write 似乎为您提供了一个可写文件,您可以将其 .dump 您的 JSON 文件。我仍然不确定它目前是否在 AWS 中实现。

如果您有足够的备用 RAM 用于 .dumps(),那么 key.set_contents_from_string 应该可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 2021-03-18
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多