Data Ingestion¶
Schema-aware data reading functions.
CSV Reading¶
read_csv¶
nyctea.ingest.readers.read_csv(path, schema, lazy=None, *, typed=False)
¶
Read a CSV with all columns as Utf8 without dtype inference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to CSV file. |
required |
schema
|
SchemaModel
|
SchemaModel describing the expected columns. |
required |
lazy
|
bool | None
|
Optional override. Defaults to schema.lazy. |
None
|
typed
|
bool
|
When True, read with schema-declared dtypes (like Pandera/Patito). When False (default), read all columns as Utf8 and rely on parsing/coercion. |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame | LazyFrame
|
pl.LazyFrame or pl.DataFrame depending on lazy flag. |
Note
When typed=False, uses infer_schema=False to read all columns as strings, which is more efficient than building a full schema_overrides dict. When typed=True, uses schema_overrides with synonym support.
Source code in src/nyctea/ingest/readers.py
Parquet Reading¶
read_parquet¶
nyctea.ingest.readers.read_parquet(path, schema, lazy=None)
¶
Read Parquet using native types from the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path | list[str] | list[Path]
|
Path or paths to Parquet files. |
required |
schema
|
SchemaModel
|
SchemaModel describing the expected columns. |
required |
lazy
|
bool | None
|
Optional override. Defaults to schema.lazy. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame | LazyFrame
|
pl.LazyFrame or pl.DataFrame depending on lazy flag. |
Source code in src/nyctea/ingest/readers.py
Usage Examples¶
Reading CSV with String Types (Recommended)¶
This is the recommended approach for validation workflows:
from nyctea.ingest import read_csv
from nyctea.schema.model import SchemaModel
schema = SchemaModel.from_yaml_file("schema.yaml")
# All columns read as strings
lf = read_csv("data.csv", schema, lazy=True)
This prevents Polars from inferring types, giving Nyctea full control over type coercion and error handling.
Reading CSV with Declared Types¶
Use this when you want Polars to directly cast to the schema dtypes (like Pandera/Patito):
Handling Synonyms¶
The readers automatically match physical column names using canonical names and synonyms:
# Schema defines:
# canonical: "passenger_id"
# synonym: "PassengerId"
# CSV has column "PassengerId"
lf = read_csv("titanic.csv", schema, lazy=True)
# Column is automatically matched!
Lazy vs Eager¶
Control whether to return a LazyFrame or DataFrame:
# LazyFrame (recommended for large data)
lf = read_csv("data.csv", schema, lazy=True)
# DataFrame (eager evaluation)
df = read_csv("data.csv", schema, lazy=False)
# Use schema default
lf_or_df = read_csv("data.csv", schema) # Uses schema.lazy
Advanced Usage¶
Multiple Files¶
from nyctea.ingest import read_parquet
# Read multiple Parquet files
lf = read_parquet(["part1.parquet", "part2.parquet"], schema, lazy=True)
Custom Schema Overrides¶
For advanced use cases, you can access the schema override dict:
import polars as pl
from nyctea.schema.model import SchemaModel
schema = SchemaModel.from_yaml_file("schema.yaml")
# Build custom overrides
schema_overrides = {}
for name, col_schema in schema.columns.items():
schema_overrides[name] = pl.Utf8
for synonym in col_schema.synonyms:
schema_overrides[synonym] = pl.Utf8
# Use directly with Polars
lf = pl.scan_csv("data.csv", schema_overrides=schema_overrides)