How to Use with Poldantic

poldantic bridges Pydantic models and Polars schemas. It can derive a Polars schema from a Pydantic model (to_polars_schema) or generate a Pydantic model from a Polars schema (to_pydantic_model). arrowmodel completes the round trip by converting Polars DataFrames back into Pydantic model instances.

Prerequisites: poldantic, polars, and arrowmodel installed.

Model-first: Pydantic model to Polars schema and back

When your Pydantic model is the source of truth, use to_polars_schema to create DataFrames that match your model, then arrowmodel to convert back:

import polars as pl
from poldantic import to_polars_schema
from arrowmodel import ArrowModel


class User(ArrowModel):
    id: int
    name: str
    score: float


# Derive a Polars schema from the Pydantic model
schema = to_polars_schema(User)
# {'id': Int64, 'name': String, 'score': Float64}

# Create or read a DataFrame using that schema
df = pl.DataFrame(
    {
        "id": [1, 2, 3],
        "name": ["Alice", "Bob", "Carol"],
        "score": [9.5, 8.0, 7.3],
    },
    schema=schema,
)

# Convert back to Pydantic model instances
users = User.convert(df)
print(users[0].name)  # Alice
print(users[1].score)  # 8.0

The schema dict ensures the DataFrame columns have the exact Polars types that correspond to your model’s field types, avoiding type mismatches at conversion time.

Schema-first: Polars schema to Pydantic model

When a Polars schema already exists (from a Parquet file, database, or shared contract), use to_pydantic_model to generate a matching Pydantic model, then convert with arrowmodel:

import polars as pl
from poldantic import to_pydantic_model
from arrowmodel import model_convert

# Existing Polars schema -- perhaps from a Parquet file or a shared definition
polars_schema = {"order_id": pl.Int64, "customer": pl.String, "total": pl.Float64}

# Generate a Pydantic model from the schema
Order = to_pydantic_model(polars_schema, "Order", force_optional=False)

# Read data using that schema
df = pl.DataFrame(
    {
        "order_id": [101, 102],
        "customer": ["Acme Corp", "Globex"],
        "total": [1500.00, 2300.50],
    },
    schema=polars_schema,
)

# Convert to model instances
orders = model_convert(Order, df)
print(orders[0].customer)  # Acme Corp

Note

Models generated by to_pydantic_model are standard Pydantic BaseModel subclasses, not ArrowModel subclasses. Use model_convert() or ArrowModelConverter to convert them.

Why this works without pyarrow

Polars DataFrames expose the Arrow PyCapsule Interface, the same protocol pyarrow uses. arrowmodel accepts any PyCapsule-compatible input, so Polars DataFrames work directly – no intermediate pyarrow conversion.

Tip

The same pattern works with any Arrow-PyCapsule-compatible library: pyarrow, Polars, nanoarrow, and others.