Getting started¶
Install¶
pip install 'rhizodat[postgres,clickhouse,drevo,iceberg]'
Each store's driver is an extra: install only those you use. rhizodat[ingest]
adds file imports, rhizodat[mcp] the MCP server, rhizodat[native] the core in
Rust (rhizodat_native, prebuilt wheels for Linux and macOS). Embedded drevo
(drevo:///) needs drevo-py, which is not on PyPI yet and is built from source.
Run the stores¶
The repository's compose.yaml runs every store on 127.0.0.1 with empty,
throw-away data:
docker compose --profile clickhouse up -d --wait
The first entity¶
An order whose money lives in PostgreSQL and whose links live in the graph. Each write is one atomic meta-transaction over both stores; every version is kept, so the order can be read as it was at any moment:
"""Quickstart: one entity, two stores, every version kept.
An order's money lives in PostgreSQL and its links in the drevo graph. Each
write is one atomic meta-transaction over both; reads see any past moment.
"""
import time
from datetime import UTC, datetime
from decimal import Decimal
from _stores import GRAPH, JOURNAL, PG
from rhizodat import Rhizodat, entity
@entity(stores={"pg": ["status", "amount"], "graph": ["customer"]}, name="shop.Order")
class Order:
status: str
amount: Decimal
customer: str
with Rhizodat(stores={"pg": PG, "graph": GRAPH}, journal=JOURNAL) as dat:
orders = dat.repository(Order)
order = Order(status="new", amount=Decimal("10.00"), customer="ada")
orders.add(order) # one meta-transaction across PostgreSQL and drevo
before = datetime.now(UTC)
time.sleep(0.01) # the update must come after `before`
order.status = "paid"
orders.update(order)
print(orders.get(order.dat_id).status) # paid
print(orders.get(order.dat_id, as_of=before).status) # new
print([v.status for v in orders.history(order.dat_id)]) # ['new', 'paid']
python examples/quickstart.py
Next: more examples, or how the meta-transactions behind this work.