我有一个特定的用例,我想以特定的前缀将对象上传到S3。这个前缀处已经存在一个文件,我想用这个新文件替换那个文件。我正在使用boto3做同样的事情,我得到以下错误。桶版本控制是关闭的,因此我希望在这种情况下文件被覆盖。但是,我得到了以下错误:
{
"errorMessage": "An error occurred (InvalidRequest) when calling the CopyObject operation: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.",
"errorType": "ClientError",
"stackTrace": [
" File "/var/task/lambda_function.py", line 25, in lambda_handlern s3.Object(bucket,product_key).copy_from(CopySource=bucket + '/' + product_key)n",
" File "/var/runtime/boto3/resources/factory.py", line 520, in do_actionn response = action(self, *args, **kwargs)n",
" File "/var/runtime/boto3/resources/action.py", line 83, in __call__n response = getattr(parent.meta.client, operation_name)(*args, **params)n",
" File "/var/runtime/botocore/client.py", line 386, in _api_calln return self._make_api_call(operation_name, kwargs)n",
" File "/var/runtime/botocore/client.py", line 705, in _make_api_calln raise error_class(parsed_response, operation_name)n"
]
}
这是我到目前为止所尝试的。
import boto3
import tempfile
import os
import tempfile
print('Loading function')
s3 = boto3.resource('s3')
glue = boto3.client('glue')
bucket='my-bucket'
bucket_prefix='my-prefix'
def lambda_handler(_event, _context):
my_bucket = s3.Bucket(bucket)
# Code to find the object name. There is going to be only one file.
for object_summary in my_bucket.objects.filter(Prefix=bucket_prefix):
product_key= object_summary.key
print(product_key)
#Using product_key variable I am trying to copy the same file name to the same location, which is when I get an error.
s3.Object(bucket,product_key).copy_from(CopySource=bucket + '/' + product_key)
# Maybe the following line is not required
s3.Object(bucket,bucket_prefix).delete()
我有一个非常特殊的原因复制相同的文件到相同的位置。AWS GLue在将同一个文件加入书签后不会选择它。当我再次复制文件时,我希望Glue书签将被删除,并且Glue作业将认为它是一个新文件。
我不太在意这个名字。如果你能帮助我修改上面的代码,以产生一个新的文件在相同的前缀级别,将工作为好。但这里必须有一个文件。可以将此文件视为从关系数据库购买到S3的产品的静态列表。
感谢使用作业书签跟踪已处理数据- AWS Glue:
对于Amazon S3输入源,AWS Glue作业书签检查对象的最后修改时间,以验证哪些对象需要重新处理。如果自上次作业运行以来输入的源数据已被修改,则在再次运行作业时将重新处理这些文件。
所以,看来你的理论是可行的!
然而,正如错误信息所述,不允许在不改变对象的元数据、存储类、网站重定向位置或加密属性的情况下将S3对象复制到自身。
因此,您可以添加一些元数据作为复制过程的一部分它会成功的。例如:s3.Object(bucket,product_key).copy_from(CopySource=bucket + '/' + product_key, Metadata={'foo': 'bar'})