Polars写入分区Parquet至S3时的两类异常行为咨询:本地文件残留与权限报错
Polars写入分区Parquet至S3时的两类异常行为咨询:本地文件残留与权限报错
我在使用Polars写入分区Parquet到S3时遇到了不符合直觉的行为:
- 当
use_pyarrow=False时,文件会先在本地创建副本再上传,但上传后不会自动清理本地文件- 当
use_pyarrow=True时,会报错:Uploading to <file> FAILED with error When initiating multiple part upload for key <directory> in bucket <bucket>: AWS Error ACCESS_DENIED during CreateMultipartUpload operation: Anonymous users cannot initiate multipart uploads. Please authenticate.复现代码如下:
session = ... # boto3 session credentials = session.get_credentials() storage_options = { "aws_access_key_id": credentials.access_key, "aws_secret_access_key": credentials.secret_key, "aws_session_token": credentials.token, "aws_region": "eu-west-1", } destination = f"s3://{bucket}/{directory}" data_frame.write_parquet( destination, partition_by=partitions, storage_options=storage_options, use_pyarrow = ... # True | False, different behavior )想知道这是否是预期行为,或者我有没有遗漏什么明显的点?
你遇到的这两个问题其实是Polars在处理S3分区写入时,不同底层实现(是否启用PyArrow)带来的典型差异,咱们一个个拆解来看:
一、use_pyarrow=False时本地文件残留的问题
这其实是当前Polars原生实现的预期行为,不算bug但确实不够直观。当关闭PyArrow时,Polars会先在本地系统的临时目录(一般前缀是polars_)生成所有分区的Parquet文件,再逐个上传到S3。但目前这个流程里,Polars并没有做自动清理本地临时文件的逻辑,所以这些文件会残留下来。
临时解决办法:
- 上传完成后,你可以手动定位到系统临时目录,找到以
polars_开头的临时文件夹并删除; - 后续可以关注Polars的版本更新,看官方是否会加入自动清理本地临时文件的功能。
二、use_pyarrow=True时的权限报错问题
这个报错的核心原因是PyArrow的分片上传权限缺失。当启用PyArrow时,它处理大文件或多分区上传会默认使用S3的**分片上传(Multipart Upload)**机制,而你的AWS凭证对应的身份没有被授予s3:CreateMultipartUpload这个关键权限,所以触发了ACCESS_DENIED错误。要注意的是,普通的S3上传权限(比如s3:PutObject)和分片上传的权限是分开的,即使你能上传单个文件,分片上传也需要单独的权限许可。
解决办法:
- 补充IAM权限:检查你的IAM策略,确保添加了以下和分片上传相关的权限:
s3:CreateMultipartUploads3:AbortMultipartUpload(避免未完成的分片占用资源)s3:ListMultipartUploadParts
- 强制单文件上传(适合小数据集):如果暂时无法修改IAM策略,可以在
storage_options里添加PyArrow的S3配置,把multipart_threshold设置为远大于你数据集大小的值,强制PyArrow用单文件上传而非分片,绕开权限问题。比如:storage_options = { # 原有的AWS凭证配置... "aws_region": "eu-west-1", "multipart_threshold": 10 * 1024 * 1024 * 1024 # 设置为10GB,根据你的数据集调整 }
整体来看,这两种行为都是不同底层实现的特性导致的,不算你操作上的明显遗漏,根据自己的场景选择对应的解决办法就好。
内容来源于stack exchange
相关产品推荐
相关产品推荐

