Types & constraints¶
Audience: intermediate (application developers)
Truth table for what ModelVault 1.0 supports today: catalog types, row values, constraints, indexes, and query predicates — use this when mapping Pydantic or dataclass fields to storage.
Model-first workflows: Pydantic guide · Models & collections
Conservative by design
Partial implementations and shape limits are called out explicitly — not hidden.
Types (schema::Type) and row values¶
Primitive scalars¶
Bool:RowValue::Bool,ScalarValue::BoolInt64:RowValue::Int64,ScalarValue::Int64Uint64:RowValue::Uint64,ScalarValue::Uint64Float64:RowValue::Float64,ScalarValue::Float64String:RowValue::String,ScalarValue::StringBytes:RowValue::Bytes,ScalarValue::BytesUuid:RowValue::Uuid,ScalarValue::UuidTimestamp:RowValue::Timestamp,ScalarValue::Timestamp
Composites¶
Optional(T)- Value may be absent at the root (treated as
RowValue::None). - Nested optionals are supported as part of list/object trees.
List(T)RowValue::List(Vec<RowValue>)(homogeneous by validation rules).Object(fields)- Stored as
RowValue::Object(BTreeMap<String, RowValue>). - Object fields are validated recursively against the declared nested field definitions.
Enum(variants)- Stored as
RowValue::Enum(String)and validated against the allowed variant set.
Schema path shape (important limitation)¶
- Top-level field defs in a collection schema may be multi-segment paths (e.g.
["profile","timezone"]). - This is a first-class way to define nested leaf fields without requiring a top-level
Type::Object(...)field. - Field paths must be non-empty and have no empty segments.
- Field paths must be unique (no duplicates).
- Parent/child conflicts are rejected (e.g. defining both
["a"]and["a","b"]). - The primary key must remain a single-segment top-level scalar field (1.0 contract simplification).
Record payload versions (on disk)¶
- v1: primitives-only, schema-ordered non-PK values (read compatibility)
- v2: composite
RowValueencoding, schema-ordered non-PK values (default for single-segment schema field defs) - v3: encodes each non-PK value with its full
FieldPath(required for multi-segment schema field defs)
See: Record encodings (v1–v3).
Constraints (schema::Constraint)¶
Constraints are enforced on write (insert/replace), after type checks:
- Numeric:
MinI64,MaxI64,MinU64,MaxU64,MinF64,MaxF64 - Length:
MinLength,MaxLength(string bytes length or list length) - String shape:
Regex,Email,Url - Non-empty:
NonEmpty(string/bytes/list)
Indexes¶
- Kinds:
Unique,NonUnique - Indexed value type: index keys are derived from a scalar value at the index path.
- Paths
- Index paths may be nested (e.g.
["profile","timezone"]) as long as the stored row value at that path is a scalar. - Maintenance
- Index maintenance is transactional and persisted via
SegmentType::Index. - Inserts use replace-by-primary-key semantics; index deltas are applied for replace/delete.
Queries (typed query AST)¶
Predicates¶
- Equality:
path == value - Boolean composition:
AND,OR - Ranges:
<,<=,>,>=(where supported by the scalar type)
Operators¶
limit: supportedorder_by: supported- May spill to ephemeral
Tempsegments on file-backed databases to avoid unbounded memory usage. - Projection: supported (subset projections by field paths)
SQL / DB-API (Python)¶
- SQL text is intentionally minimal and exists to support a read-only subset of DB-API.
- For application code, prefer the Rust/Python typed query builder APIs.