MATERIALIZED columns compute and store values at INSERT time, making queries faster at the cost of disk space and insert overhead.
MATERIALIZED columns are automatically calculated at insert time and cannot be set by users.
from typing import Annotated, Anyfrom datetime import datetime, datefrom moose_lib import OlapTable, OlapConfig, Key, ClickHouseMaterialized, ClickHouseCodec, UInt64from pydantic import BaseModel class UserEvents(BaseModel): id: Key[str] timestamp: datetime user_id: str log_blob: Annotated[Any, ClickHouseCodec("ZSTD(3)")] # Extract date for partitioning event_date: Annotated[date, ClickHouseMaterialized("toDate(timestamp)")] # Precompute hash for fast lookups user_hash: Annotated[UInt64, ClickHouseMaterialized("cityHash64(user_id)")] # Parse JSON once at insert (expensive) combination_hash: Annotated[ list[UInt64], ClickHouseMaterialized("arrayMap(kv -> cityHash64(kv.1, kv.2), JSONExtractKeysAndValuesRaw(toString(log_blob)))"), ClickHouseCodec("ZSTD(1)") ] user_events_table = OlapTable[UserEvents]( "UserEvents", OlapConfig( order_by_fields=["user_hash", "event_date"], partition_by="toYYYYMM(event_date)" ))Date/Time Extraction:
toDate(timestamp) - Extract date for partitioningtoHour(timestamp) - Extract hour for time-series analysistoStartOfMonth(timestamp) - Monthly aggregation keyHash Functions:
cityHash64(user_id) - Fast user lookupscityHash64(user_id, session_id) - Combined hash for deduplicationJSON Processing:
JSONExtractString(log_blob, 'level') - Extract specific fieldarrayMap(kv -> cityHash64(...), JSONExtractKeysAndValuesRaw(...)) - Hash all key-value pairsUse the exact field names from your data model. Moose preserves your naming convention (camelCase in TypeScript, snake_case in Python) in ClickHouse columns.
Restrictions:
Schema Changes:
ALTER TABLE ADD COLUMN ... MATERIALIZED exprALTER TABLE MODIFY COLUMN ... MATERIALIZED new_expr (preserves existing values)ALTER TABLE MODIFY COLUMN ... REMOVE MATERIALIZEDWhen using moose init --from-remote, MATERIALIZED column definitions are automatically preserved:
moose init my-app --from-remote --language typescript
# Generated models include ClickHouseMaterialized annotations