Существует безсерверное решение с использованием AWS Glue! (я чуть не умер, когда понял это)
Это решение состоит из двух частей:
- Лямбда-функция, которая запускается S3 при загрузке ZIP-файла и создает GlueJobRun - передавая ключ объекта S3 в качестве аргумента Glue.
- Задание Glue, которое распаковывает файлы (в памяти!)и загружает обратно на S3.
См. Мой код ниже, который распаковывает ZIP-файл и помещает содержимое обратно в ту же корзину (настраивается).
Пожалуйста, подтвердите, если это полезно:)
Лямбда-скрипт (python3), который вызывает задание по склеиванию под названием YourGlueJob
import boto3
import urllib.parse
glue = boto3.client('glue')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
print(key)
try:
newJobRun = glue.start_job_run(
JobName = 'YourGlueJob',
Arguments = {
'--bucket':bucket,
'--key':key,
}
)
print("Successfully created unzip job")
return key
except Exception as e:
print(e)
print('Error starting unzip job for' + key)
raise e
Скрипт задания по склеиванию AWS дляраспакуйте файлы
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
## @params: [JOB_NAME]
args = getResolvedOptions(sys.argv, ['JOB_NAME','bucket','key'],)
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
import boto3
import zipfile
import io
from contextlib import closing
s3 = boto3.client('s3')
s3r = boto3.resource('s3')
bucket = args["bucket"]
key = args["key"]
obj = s3r.Object(
bucket_name=bucket,
key=key
)
buffer = io.BytesIO(obj.get()["Body"].read())
z = zipfile.ZipFile(buffer)
list = z.namelist()
for filerr in list:
print(filerr)
y=z.open(filerr)
arcname = key + filerr
x = io.BytesIO(y.read())
s3.upload_fileobj(x, bucket, arcname)
y.close()
print(list)
job.commit()