[英]how generate and write stream data to s3 on the fly with python and boto3?
如何使用python
和boto3
將動態生成的數據動態寫入S3
?
我想實現這樣的事情:
from io import BytesIO
from boto3 import ???
s3_opened_stream = ???
for i in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y', 'z']:
data = (i*1000).decode('utf-8')
s3_opened_stream.append_chunk(BytesIO(data))
# OR something like
with ??? as s3_opened_stream:
for i in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y', 'z']:
data = (i*1000).decode('utf-8')
s3_opened_stream.append_chunk(BytesIO(data))
並期望看到結果文件,如:
aaaaaa......
bbbbbb......
cccccc......
.....
其中每一行都將附加到相同的 S3 object。
我檢查了互聯網上的示例,並且在第一步和生成上傳到 S3 之后,到處都完全生成了數據。
我嘗試使用這些示例,例如:
from io import BytesIO
from boto3.s3.transfer import TransferConfig
from boto3 import resource
config = TransferConfig(
# set possible lower size to force multipart-upload in any case
multipart_threshold=1,
max_concurrency=1,
multipart_chunksize=5242880,
use_threads=False
)
bucket = resource(
service_name='s3',
region_name=params['region_name'],
endpoint_url=params['endpoint_url'],
aws_access_key_id=params['aws_access_key_id'],
aws_secret_access_key=params['aws_secret_access_key']
).Bucket(params['bucket_name'])
with BytesIO() as one_chunk:
for line in lines:
# write new line inside one_chunk
...
# write data to object
bucket.upload_fileobj(one_chunk, obj_path, Config=config, Callback=None)
# clear chunk data to release RAM
one_chunk.truncate(0)
但是upload_fileobj
每次都用新行而不是 append 重寫 object 。
換句話說,我想在 append 模式下打開 S3 object(如with open('path', mode='a')
)和將在循環中生成的 append 行。 因為實際生成的文件非常大,無法完整存儲在 RAM memory 中
最后我放棄嘗試理解boto3
代碼。 它非常復雜,並且類不能簡單地擴展。
看起來smart_open
是最簡單的解決方案:
我用4GB
的輸入文件檢查了這段代碼
from boto3 import Session
from smart_open import open
c = Session(
aws_access_key_id=id,
aws_secret_access_key=key
).client('s3', endpoint_url='http://minio.local:9000') # I use minio for testing
read_path="bucket_name/in.csv"
write_path="bucket_name/out.csv"
with open(f"s3://{read_path}", mode='rb', transport_params={'client': c}) as fr:
with open(f"s3://{write_path}", mode='wb', transport_params={'client': c}) as fw:
for line in fr:
fw.write(line)
它就像一個魅力。 350MB
使用量峰值約為 350MB。 (通過htop
的RES
值檢查)
RES:進程使用了多少物理 RAM,以千字節為單位。
RES 代表駐留大小,它准確表示一個進程正在消耗多少實際物理 memory。 (這也直接對應於 %MEM 列)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.