Python 如何从S3存储桶中读取CSV文件、对其应用某些if语句、编写新的更新CSV文件并将其放入S3存储桶中?
我无法将新CSV文件写入S3存储桶。我希望能够读取S3存储桶中的CSV文件,如果CSV中的某个值符合特定要求,我希望将其更改为其他值。我读到不可能编辑S3对象,所以每次都需要创建一个新对象。简而言之,我想从S3存储桶中的另一个CSV文件创建一个新的、更新的CSV文件,并应用更改 我尝试使用DictWriter和DictReader,但我总是遇到DictWriter的问题。我可以正确地读取CSV文件,但当我尝试更新它时,与DictWriter有许多明显不同的问题。现在,我遇到的问题是Python 如何从S3存储桶中读取CSV文件、对其应用某些if语句、编写新的更新CSV文件并将其放入S3存储桶中?,python,amazon-web-services,csv,amazon-s3,aws-lambda,Python,Amazon Web Services,Csv,Amazon S3,Aws Lambda,我无法将新CSV文件写入S3存储桶。我希望能够读取S3存储桶中的CSV文件,如果CSV中的某个值符合特定要求,我希望将其更改为其他值。我读到不可能编辑S3对象,所以每次都需要创建一个新对象。简而言之,我想从S3存储桶中的另一个CSV文件创建一个新的、更新的CSV文件,并应用更改 我尝试使用DictWriter和DictReader,但我总是遇到DictWriter的问题。我可以正确地读取CSV文件,但当我尝试更新它时,与DictWriter有许多明显不同的问题。现在,我遇到的问题是 # Func
# Function to be pasted into AWS Lambda.
# Accesses S3 bucket, opens the CSV file, receive the response line-by-line,
# To be able to access S3 buckets and the objects within the bucket
import boto3
# To be able to read the CSV by using DictReader
import csv
# Lambda script that extracts, transforms, and loads data from S3 bucket 'testing-bucket-1042' and CSV file 'Insurance.csv'
def lambda_handler(event, context):
s3 = boto3.resource('s3')
bucket = s3.Bucket('testing-bucket-1042')
obj = bucket.Object(key = 'Insurance.csv')
response = obj.get()
lines = response['Body'].read().decode('utf-8').split()
reader = csv.DictReader(lines)
with open("s3://testing-bucket-1042/Insurance.csv", newline = '') as csvfile:
reader = csv.DictReader(csvfile)
fieldnames = ['county', 'eq_site_limit']
writer = csv.DictWriter(lines, fieldnames=fieldnames)
for row in reader:
writer.writeheader()
if row['county'] == "CLAY": # if the row is under the column 'county', and contains the string "CLAY"
writer.writerow({'county': 'CHANGED'})
if row['eq_site_limit'] == "0": # if the row is under the column 'eq_site_limit', and contains the string "0"
writer.writerow({'eq_site_limit': '9000'})
现在,我得到的错误是,我在尝试打开CSV时使用的路径“s3://testing-bucket-1042/Insurance.CSV”据说不存在
错误是
“errorMessage:“[Errno 2]没有这样的文件或目录:'s3://testing-bucket-1042/Insurance.csv'”,
“errorType”:“FileNotFoundError”
如果使用DictWriter,正确的方法是什么?首先
s3:\\
不是常见的(文件)协议,因此您会收到错误消息。很好,你表明了你的意图
好的,我重构了你的代码
import codecs
import boto3
# To be able to read the CSV by using DictReader
import csv
from io import StringIO
# Lambda script that extracts, transforms, and loads data from S3 bucket 'testing-bucket-1042' and CSV file 'Insurance.csv'
def lambda_handler(event, context):
s3 = boto3.resource('s3')
bucket = s3.Bucket('testing-bucket-1042')
obj = bucket.Object(key = 'Insurance.csv')
stream = codecs.getreader('utf-8')(obj.get()['Body'])
lines = list(csv.DictReader(stream))
### now you have your object there
csv_buffer = StringIO()
out = csv.DictWriter(csv_buffer, fieldnames=['county', 'eq_site_limit'])
for row in lines:
if row['county'] == "CLAY":
out.writerow({'county': 'CHANGED'})
if row['eq_site_limit'] == "0":
out.writerow({'eq_site_limit': '9000'})
### now write content into some different bucket/key
s3client = boto3.client('s3')
s3client.put_object(Body=csv_buffer.getvalue().encode(encoding),
Bucket=...targetbucket, Key=...targetkey)
我希望这能奏效。基本上有几个技巧:
- 使用
直接从s3存储桶传输csv数据编解码器
- 使用
在内存中创建BytesIO
可以写入的流李>csv.DictWriter
- 完成后,“上传”内容的一种方法是通过
s3。客户端的
put\u对象
方法(如AWS中所述)
- 将对象从Amazon S3下载到
目录/tmp
- 执行所需的业务逻辑(读文件、写文件)
- 将生成的文件上载到Amazon S3
download_file()
和upload_file()
可以避免担心内存流。这意味着您可以采用通常在文件上运行的逻辑(例如在您自己的计算机上),然后将其应用于从S3获取的文件
这取决于个人喜好。您可以使用S3的流媒体功能随时进行更改。它更适合于文本操作工具,如
awk
和sed
例如:
aws s3 cp s3://bucketname/file.csv - | sed 's/foo/bar/g' | aws s3 cp - s3://bucketname/new-file.csv
AWS文档:您可能应该使用boto3 API上传生成的CSV,但如果出于某种原因确实需要使用常规Python文件接口到S3,那么您可能需要查看一下。感谢您的快速响应!我仍然遇到out.writerow({'county':'CHANGED'})的问题。错误消息表示“需要类似字节的对象,而不是'str'”。你能帮我做这个吗?