我有一个Python代码,可以使用pandas读取位于
的s3文件s3://bucket_name/table_name/file.parquet
如果我提供带有上面文件名的拉取路径,我的Python就可以工作。 但是,如果我提供目录路径作为前缀来列出所有对象,然后获取每个对象,则会出现访问被拒绝错误:
bucket=bucket_name
key=table_name/
objects=s3.list_objects(Bucket=bucket,Prefix=key)['Contents']
print(objects)
dfs=[]
for obj in objects:
file_key=obj['Key']
obj=s3.get_object(Bucket=bucket,Key=file_key)
df_single=pd.read_parquet(BytesIO(obj['Body'].read()))
dfs.append(df_single)
df=pd.concat(dfs, ignore_index=True)
我发现标题中有错误。
我检查了存储桶的 IAM 策略。我们允许存储桶使用 s3.ListBucket 和 s3.getObject
"s3://bucket_name*/*"
请注意,
ListBucket
需要存储桶的权限(没有/*
),而GetObject
适用于对象级别并且可以使用*
通配符。
此外,如果您要向同一 AWS 账户中的 IAM 用户或 IAM 角色授予访问权限,最好通过 IAM 用户/角色的 IAM 策略授予权限,而不是使用存储桶策略。
此 IAM 策略可以应用于 IAM 用户/IAM 角色并向该用户授予对整个存储桶的访问权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::BUCKET-NAME"]
},
{
"Action": ["s3:GetObject"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::BUCKET-NAME/*"]
}
]
}
如果您要使用存储桶策略(不建议),则需要添加Principal
来识别谁接收访问权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::BUCKET-NAME"],
"Principal": "arn:aws:iam::123456789012:user/USERNAME"
},
{
"Action": ["s3:GetObject"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::BUCKET-NAME/*"],
"Principal": "arn:aws:iam::123456789012:user/USERNAME"
}
]
}
如果需要,这些策略可以进一步限制为仅授予对特定目录的访问权限。请参阅: