如何用polars从AWS S3读取parquet文件

2 投票
1 回答
129 浏览
提问于 2025-04-14 17:27

根据文档,我写了下面这个脚本,但它运行失败了。

import boto3
import polars as pl
import os

session = boto3.Session(profile_name=os.environ["AWS_PROFILE"])
credentials = session.get_credentials()
current_credentials = credentials.get_frozen_credentials()
# Specify your S3 bucket and file path
s3_bucket = "bucket"
s3_file_path = "path/file.parquet"

# Create the full S3 path
s3_path = f"s3://{s3_bucket}/{s3_file_path}"

storage_options = {
    'aws_access_key_id': current_credentials.access_key,
    'aws_secret_access_key': current_credentials.secret_key,
    'aws_region': 'us-east-1' credentials
}

df = pl.scan_parquet(s3_path, storage_options=storage_options)


运行后出现了下面的错误信息,我知道这是因为没有权限访问文件。

ComputeError: 一般的 S3 错误:客户端错误,状态 403 禁止访问:没有内容

版本信息:

  • Python '3.9.18'
  • polars '0.20.14'
  • boto3 '1.34.58'

我是在 macos 系统上运行的。

我也能通过设置 AWS_PROFILE 环境变量,成功使用 pandas 读取 parquet 文件。

我是不是错误使用了 storage_options?它似乎无法使用 'aws_profile' 这个键值对来提取本地的配置凭证?

1 个回答

2

你可能还需要传递相应的会话令牌,方法如下。

import polars as pl
import boto3

profile_name = "your-profile"
s3_path = "s3://my-s3-bucket/my_file.parquet"

session = boto3.session.Session(profile_name=profile_name)
credentials = session.get_credentials().get_frozen_credentials()

df = pl.read_parquet(
    s3_path,
    storage_options={
        "aws_access_key_id": credentials.access_key,
        "aws_secret_access_key": credentials.secret_key,
        "aws_session_token": credentials.token,
        "aws_region": session.region_name,
    },
)

来自AWS访问密钥的文档:

这段话是说,AWS会话令牌是用来验证用户身份的凭证的一部分。你会在成功请求角色时收到这个临时凭证的值。只有在你手动指定临时安全凭证时,才需要会话令牌。不过,我们建议你总是使用临时安全凭证,而不是长期凭证。关于安全的建议,可以查看IAM中的安全最佳实践

撰写回答