sea-orm-sync/src/entity/ARROW.md
This document explains Apache Arrow's decimal and timestamp formats and their integration with SeaORM.
Apache Arrow provides fixed-point decimal types for representing precise numeric values with a specific precision and scale:
DataType::Decimal64(precision, scale)
precision (u8): Total number of decimal digits (1-18)scale (i8): Number of digits after decimal point (can be negative)Decimal64(10, 2) represents numbers like 12345678.90DataType::Decimal128(precision, scale)
precision (u8): Total number of decimal digits (1-38)scale (i8): Number of digits after decimal point (can be negative)Decimal128(20, 4) represents numbers like 9999999999999999.9999DataType::Decimal256(precision, scale)
precision (u8): Total number of decimal digits (1-76)scale (i8): Number of digits after decimal point (can be negative)Decimal256(76, 20) for extreme precision requirements123.45)12345)12300 stored as 123)Examples:
Decimal64(10, 2) → Can store: -99999999.99 to 99999999.99 (compact, i64)
Decimal64(5, 0) → Can store: -99999 to 99999 (integers, compact)
Decimal128(20, 4) → Can store: -9999999999999999.9999 to 9999999999999999.9999
Decimal128(10, 4) → Can store: -999999.9999 to 999999.9999
Decimal256(38, 10) → High precision: up to 28 digits before, 10 after decimal
SeaORM supports two Rust decimal libraries:
with-rust_decimal)rust_decimal::DecimalValue::Decimalwith-bigdecimal)bigdecimal::BigDecimalValue::BigDecimalwith-rust_decimal is enabledDecimal::from_i128_with_scale()ColumnType::Decimal(Some((precision, scale)))with-bigdecimal is enabled (fallback if rust_decimal not available)ColumnType::Decimal(Some((precision, scale)))with-rust_decimal is enabledi128 to Decimal::from_i128_with_scale()ColumnType::Decimal(Some((precision, scale)))with-bigdecimal is enabled (fallback if rust_decimal fails or not available)ColumnType::Decimal(Some((precision, scale))) or ColumnType::Money(_)with-bigdecimal is enabledColumnType::Decimal(Some((precision, scale)))Decimal64Array:
with-rust_decimal first (always fits, precision ≤ 18)with-bigdecimal if neededDecimal128Array:
with-rust_decimal first (if precision/scale fit)with-bigdecimal if neededDecimal256Array:
with-bigdecimal (rust_decimal can't handle precision > 28)Null Handling:
Value::Decimal(None) or Value::BigDecimal(None) for null valuesArrow provides several temporal types for representing dates, times, and timestamps with varying precision.
DataType::Date32DataType::Date64Time32(TimeUnit::Second) - seconds since midnightTime32(TimeUnit::Millisecond) - milliseconds since midnightTime64(TimeUnit::Microsecond) - microseconds since midnightTime64(TimeUnit::Nanosecond) - nanoseconds since midnightTimestamp types represent absolute points in time with optional timezone.
Timestamp(TimeUnit, Option<String>)Variants:
DataType::Timestamp(TimeUnit::Second, None) // No timezone
DataType::Timestamp(TimeUnit::Millisecond, None) // No timezone
DataType::Timestamp(TimeUnit::Microsecond, None) // No timezone
DataType::Timestamp(TimeUnit::Nanosecond, None) // No timezone
DataType::Timestamp(TimeUnit::Second, Some("UTC".into())) // With timezone
DataType::Timestamp(TimeUnit::Microsecond, Some("UTC".into())) // With timezone
DataType::Timestamp(TimeUnit::Nanosecond, Some("UTC".into())) // With timezone
TimeUnit Precision:
SeaORM supports two Rust datetime libraries for temporal types:
with-chrono) - Preferredchrono::NaiveDate - Date without timezonechrono::NaiveTime - Time without date/timezonechrono::NaiveDateTime - DateTime without timezonechrono::DateTime<Utc> - DateTime with UTC timezoneValue::ChronoDate(Option<NaiveDate>)Value::ChronoTime(Option<NaiveTime>)Value::ChronoDateTime(Option<NaiveDateTime>)Value::ChronoDateTimeUtc(Option<DateTime<Utc>>)with-time) - Alternativetime::Date - Date without timezonetime::Time - Time without date/timezonetime::PrimitiveDateTime - DateTime without timezonetime::OffsetDateTime - DateTime with timezone offsetValue::TimeDate(Option<Date>)Value::TimeTime(Option<Time>)Value::TimeDateTime(Option<PrimitiveDateTime>)Value::TimeDateTimeWithTimeZone(Option<OffsetDateTime>)time crate ecosystemchrono, with automatic fallback to time if type mismatchchrono:
Date32Array → chrono::NaiveDate
Date64Array → chrono::NaiveDate
time:
Date32Array → time::Date
Date64Array → time::Date
chrono:
Time32(Second) → chrono::NaiveTime
Time32(Millisecond) → chrono::NaiveTime
Time64(Microsecond) → chrono::NaiveTime
Time64(Nanosecond) → chrono::NaiveTime
time:
Time32(Second) → time::Time
Time32(Millisecond) → time::Time
Time64(Microsecond) → time::Time
Time64(Nanosecond) → time::Time
Without Timezone:
Timestamp(TimeUnit, None)→ chrono::NaiveDateTime→ time::PrimitiveDateTimeColumnType::DateTime or ColumnType::TimestampWith Timezone:
Timestamp(TimeUnit, Some(tz))→ chrono::DateTime<Utc>→ time::OffsetDateTimeColumnType::TimestampWithTimeZone| TimeUnit | Conversion Method | Precision |
|---|---|---|
| Second | from_timestamp(secs, 0) | 1 second |
| Millisecond | from_timestamp_millis(ms) | 1 millisecond |
| Microsecond | from_timestamp_micros(us) | 1 microsecond |
| Nanosecond | from_timestamp_nanos(ns) or from_timestamp(secs, nsecs) | 1 nanosecond |