Getting Started¶
In this tutorial you will install arrowmodel, define a Pydantic model, create some Arrow data, and convert it into a list of typed model instances – all in under 5 minutes. By the end you will have a working feel for the library’s core loop: Arrow data in, Pydantic models out.
Prerequisites
Python 3.11 or later
Familiarity with Pydantic v2
BaseModeldefinitionsFamiliarity with pyarrow
RecordBatch(or any Arrow-producing library)
Install arrowmodel¶
arrowmodel ships as a pre-built binary wheel. No Rust toolchain is needed on your machine.
pip install arrowmodel
uv add arrowmodel
You will also need pyarrow (or another Arrow-PyCapsule-compatible library such as Polars) to create Arrow data. If you do not have it already:
pip install pyarrow
uv add pyarrow
Define a Pydantic model¶
Start by defining the shape of the data you expect. This is a standard Pydantic v2 model – nothing special yet.
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
score: float
Each field name corresponds to a column name in the Arrow data you will convert next.
Create some Arrow data¶
Build a RecordBatch with columns that match your model fields.
import pyarrow as pa
batch = pa.record_batch(
{
"id": [1, 2, 3],
"name": ["Alice", "Bob", "Carol"],
"email": ["alice@example.com", "bob@example.com", "carol@example.com"],
"score": [9.5, 8.0, 7.3],
}
)
In a real application this data would come from a database query (ADBC, Flight
SQL), a Parquet file, or a Polars DataFrame. The RecordBatch is the common
hand-off point.
Convert to model instances¶
Now for the good part. Use model_convert() to turn the
batch into a list of User instances:
from arrowmodel import model_convert
users = model_convert(User, batch)
for user in users:
print(f"{user.name} ({user.email}): {user.score}")
You should see:
Alice (alice@example.com): 9.5
Bob (bob@example.com): 8.0
Carol (carol@example.com): 7.3
That is the entire workflow. Arrow columns were mapped to model fields by name,
values were extracted directly from Arrow buffers in Rust, and each row was
assembled into a User instance via model_construct – no intermediate
Python dicts were created.
Tip
model_convert creates a fresh converter on every call. If you will
convert many batches with the same model, look at
ArrowModelConverter or the
ArrowModel base class in the
How to Choose an API Style guide – they compile the field mapping once
and reuse it.
Try with a Table¶
A Table is just multiple RecordBatch objects bundled together.
arrowmodel handles both transparently:
# Using the same User model and batch from above
table = pa.Table.from_batches([batch, batch])
users = model_convert(User, table)
print(len(users)) # 6
What you learned¶
arrowmodel installs as a binary wheel – no Rust toolchain required.
You define a Pydantic
BaseModelwhose field names match Arrow column names.model_convert()converts aRecordBatchorTableinto alistof model instances in a single call.Conversion happens in Rust via the Arrow C Data Interface – no intermediate Python dicts.
Next steps¶
How to Choose an API Style – pick between the convenience function, the converter class, or the
ArrowModelbase class.How to Use Validated Mode – enable full Pydantic validation when you need it.
Understanding Fast Path vs Validated Path – understand the performance trade-offs between the fast path and the validated path.