Files
2026-07-13 13:17:40 +08:00

83 lines
2.7 KiB
Python

from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Union
from ray.data.block import Block
from ray.data.datasource.file_based_datasource import FileBasedDatasource
if TYPE_CHECKING:
import pyarrow
class CSVDatasource(FileBasedDatasource):
"""CSV datasource, for reading and writing CSV files."""
_FILE_EXTENSIONS = [
"csv",
"csv.gz", # gzip-compressed files
"csv.br", # Brotli-compressed files
"csv.zst", # Zstandard-compressed files
"csv.lz4", # lz4-compressed files
]
def __init__(
self,
paths: Union[str, List[str]],
arrow_csv_args: Optional[Dict[str, Any]] = None,
**file_based_datasource_kwargs,
):
from pyarrow import csv
super().__init__(paths, **file_based_datasource_kwargs)
if arrow_csv_args is None:
arrow_csv_args = {}
self.read_options = arrow_csv_args.pop(
"read_options", csv.ReadOptions(use_threads=False)
)
self.parse_options = arrow_csv_args.pop("parse_options", csv.ParseOptions())
self.arrow_csv_args = arrow_csv_args
def _read_stream(self, f: "pyarrow.NativeFile", path: str) -> Iterator[Block]:
import pyarrow as pa
from pyarrow import csv
# Re-init invalid row handler: https://issues.apache.org/jira/browse/ARROW-17641
if hasattr(self.parse_options, "invalid_row_handler"):
self.parse_options.invalid_row_handler = (
self.parse_options.invalid_row_handler
)
filter_expr = (
self._predicate_expr.to_pyarrow()
if self._predicate_expr is not None
else None
)
try:
reader = csv.open_csv(
f,
read_options=self.read_options,
parse_options=self.parse_options,
**self.arrow_csv_args,
)
schema = None
while True:
try:
batch = reader.read_next_batch()
table = pa.Table.from_batches([batch], schema=schema)
if schema is None:
schema = table.schema
if filter_expr is not None:
table = table.filter(filter_expr)
yield table
except StopIteration:
return
except pa.lib.ArrowInvalid as e:
raise ValueError(
f"Failed to read CSV file: {path}. "
"Please check the CSV file has correct format, or filter out non-CSV "
"file with 'partition_filter' field. See read_csv() documentation for "
"more details."
) from e