You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars使用Glob模式读取S3多目录下CSV文件时仅读取单个文件的问题排查

Polars使用Glob模式读取S3多目录下CSV文件时仅读取单个文件的问题排查

我明白你遇到的这个问题有多让人困惑——明明glob模式看起来完全合理,read_csv却只读取第一个目录下的CSV文件,而scan_csv不仅能正常工作,甚至连storage_options都不需要。咱们一步步拆解这个问题,找到原因和解决方案:

核心原因:Eager vs Lazy API的Glob展开逻辑差异

Polars的**eager模式API(如read_csv)和lazy模式API(如scan_csv)**在处理远程存储(比如S3)的glob路径时,底层实现逻辑有关键差异:

  • 对于read_csv(eager模式):它的glob展开依赖storage_options={"expand": True}来触发,但当路径是多层级glob模式(比如prefix*/*.csv)时,eager模式的文件解析流程会存在匹配不完全的问题——它可能在找到第一个符合模式的文件后,就停止继续扫描后续的目录和文件。这就是你只读到第一个目录下CSV的原因。
  • 对于scan_csv(lazy模式):它是先扫描所有符合glob的路径,再统一执行数据收集,其glob展开是由底层文件系统处理逻辑直接支持的,不需要额外的storage_options,因此能正确匹配所有符合模式的文件。

你当前代码的问题点

你在read_csv中使用的storage_options={"expand": True}确实是为了触发glob展开,但多层级的glob模式(prefix*/*.csv)和eager模式的文件解析逻辑不兼容,导致只匹配到第一个符合条件的文件。即使你把glob模式改成明确的文件名(*/sample_csv.csv),也因为同样的逻辑问题,无法匹配后续目录下的文件。

可行的解决方案

方案1:改用Lazy API(最推荐)

既然scan_csv已经能正常工作,直接采用这个方案即可。它不仅能正确读取所有文件,还能利用Polars的lazy优化,对于大数据量场景性能更优:

import polars as pl

s3_bucket = "sample_bucket"
prefix = "abcd/efgh/ijkl/"
df = pl.scan_csv(source=f"s3://{s3_bucket}/{prefix}*/*.csv").collect()

这个方案不需要额外的storage_options,因为lazy模式的文件扫描逻辑已经原生支持S3的glob展开。

方案2:手动展开Glob路径(适用于必须用Eager API的场景)

如果你一定要使用eager模式的read_csv,可以通过s3fs手动先获取所有符合条件的S3文件路径,再将路径列表传给read_csv:

import polars as pl
from s3fs import S3FileSystem

s3_bucket = "sample_bucket"
prefix = "abcd/efgh/ijkl/"
s3 = S3FileSystem()

# 手动获取所有符合模式的S3文件路径
file_paths = [f"s3://{path}" for path in s3.glob(f"{s3_bucket}/{prefix}*/*.csv")]

# 读取所有文件
df = pl.read_csv(source=file_paths)

这种方式完全绕开了Polars eager模式的glob展开逻辑,确保所有符合条件的文件都被读取。

方案3:调整Glob模式写法(兼容性有限)

在部分场景下,调整glob模式的写法可以触发read_csv正确展开,比如使用**匹配所有子目录(需配合storage_options={"expand": True}):

import polars as pl

s3_bucket = "sample_bucket"
prefix = "abcd/efgh/ijkl/"
storage_options = {"expand": True}
df = pl.read_csv(source=f"s3://{s3_bucket}/{prefix}**/sample_csv.csv", storage_options=storage_options)

注意:这个方案的兼容性不如前两个,因为它依赖于Polars eager模式下的glob解析逻辑,可能在不同版本或存储场景下表现不一致。

补充:Polars的“隐性规则”

你提到的这种差异确实是Polars里一个容易踩坑的“部落知识”:

  • Eager模式的远程文件glob展开逻辑和Lazy模式是分开实现的,因此同一glob模式在两种模式下可能表现不同。
  • 对于S3路径,Lazy API的glob支持更完善,而Eager API需要依赖storage_options触发展开,且在多层级glob场景下存在匹配不完全的问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 09:49:29