Arrow Type Mappings¶
When arrowmodel extracts values from Arrow columns, each Arrow data type maps to a specific Python type. This page is the definitive reference for those mappings – consult it when you need to know what Python type a given Arrow column will produce in your Pydantic model.
Integer types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All Arrow integer types produce Python int. There is no overflow risk
since Python integers are arbitrary-precision.
Float types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Half-precision, widened to 64-bit |
|
|
Single-precision, widened to 64-bit |
|
|
All float types produce Python float (64-bit). Float16 and Float32
values are widened, which may introduce small floating-point representation
differences.
Decimal types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Full precision preserved |
|
|
Full precision preserved |
|
|
Up to 38 digits |
|
|
Up to 76 digits |
Decimal values are converted to decimal.Decimal with full precision – no
intermediate float conversion that would lose significant digits.
Boolean and string types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Exactly |
|
|
|
|
|
|
|
|
Date and time types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Days since epoch |
|
|
Milliseconds since epoch |
|
|
|
|
|
Milliseconds as microseconds |
|
|
|
|
|
Nanoseconds truncated to microseconds |
Note
Date32 produces datetime.date while Date64 produces
datetime.datetime. This follows Arrow’s own semantics: Date32 stores
days, Date64 stores milliseconds (with time component).
Timestamp types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
Nanoseconds truncated to microseconds |
|
|
|
Timezone-aware timestamps use Python’s ZoneInfo for the timezone. IANA
timezone strings (like "America/New_York") are preserved.
Warning
Nanosecond-precision timestamps are truncated to microsecond precision
because Python’s datetime only supports microseconds. Nanoseconds are
silently dropped, not rounded.
Duration type¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
All units converted to timedelta |
Binary types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
Length |
|
|
Note
In validated mode (validate=True), binary data is serialised as
base64-encoded strings in the JSON intermediate. Pydantic’s
model_validate_json decodes base64 back to raw bytes when the
field type is bytes, so the model field receives the correct raw
binary in both paths.
List and container types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Elements mapped recursively |
|
|
Same as |
|
|
Always |
|
|
List of key-value pairs |
Nested list types (List(List(Int64))) produce nested Python lists
(list[list[int]]).
Container elements may themselves be nested models. A List(Struct) column
whose field is annotated list[MyModel] produces a list of MyModel
instances; this threads recursively, so list[list[MyModel]],
FixedSizeList(MyModel), and struct fields containing list[MyModel] all
work. See How to Convert Nested Models.
Note
Map columns are materialised as a list of (key, value) pairs,
not a dict. This is lossless for Arrow Maps, whose keys may be non-string
or duplicated (neither of which a Python dict or JSON object can
represent). Annotate a Map field as list[tuple[K, V]]; a dict /
Mapping annotation over a Map column raises TypeError at
convert() time. Map values may be nested models
(list[tuple[str, MyModel]]).
Struct type¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
Nested |
A Struct column is converted to a nested Pydantic model when the
corresponding field is annotated as a BaseModel subclass. A null struct
produces None.
Dictionary-encoded columns¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
Same as |
Transparent decoding |
Dictionary-encoded columns are transparently decoded. A
Dictionary(Int32, Utf8) column produces str values, the same as a
plain Utf8 column.
Interval types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
All interval types are normalised to a 3-tuple of (months, days, nanoseconds)
for a consistent representation.
Union types¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
Value from active child |
Type varies per row |
|
Value from active child |
Type varies per row |
Union columns produce the Python value from the active child array for each
row. Use a Pydantic Union annotation (e.g., int | str) to accept the
varying types.
Run-end encoded columns¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
Same as value type |
Transparent decoding |
Run-end encoded columns are transparently unpacked before extraction. A
run-end encoded Utf8 column produces str values.
Null type¶
Arrow Type |
Python Type |
Notes |
|---|---|---|
|
|
Every row is |
Null handling¶
For any nullable column (regardless of type), a null value produces None
in the model instance. The corresponding Pydantic field should be typed as
Optional (e.g., str | None = None) to accept the None value.
Fields with default values that are missing from the Arrow schema use their
Pydantic default. Required fields that are missing from the Arrow schema
raise ValueError at conversion time.