Tutorial
This tutorial walks through the entire MonaDB python API.
Open Databasae
import monadb
db = monadb.() # in-memory
db = monadb.("app.db") # file-backed
A Database is a mapping of collection names to collections, and a collection is
a mapping of keys to documents. You can think of collections as persistant
python dicts.
Collections
Collections are automatically created on the first write.
# Creates a 'users' collection
users =["users"]
# Insert a document into the 'users' collection
["alice"] = {"age": 30, "email": "alice@example.com"}
# Fetch a document by its key
["alice"] # {'age': 30, 'email': 'alice@example.com'}MutableMapping
Each collection is a MutableMapping and behaves like a Python dict.
Missing keys raise KeyError, exactly as a dict does.
# Returns the 'users' collection
users =["users"]
# Checks if a document at the given key exists
"alice" in users
# Returns the length of the collection
len()
# Returns the document or default value
users.("bob", {})
# Returns document for "bob" if it exists, otherwise sets it.
users.("bob", {"age": 41})
# Updates given documents
users.({"carol": {"age": 22}, "dan": {"age": 51}})
# Removes and returns the document at key "dan"
users.("dan") # {'age': 51}
# Deletes the document at key "bob"
del["bob"]
# Iterate all key, document pairs
for key, doc in users.():
print(,)Ordering
Iteration is in key order, not insertion order.
events =["events"]
for ts in [3, 1, 2]:
[] = {"at": ts}
list() # [1, 2, 3]
list(reversed()) # [3, 2, 1]
events.() # (1, {'at': 1})
events.() # (3, {'at': 3})
Ranges are half-open, and either bound may be None:
list(.(1, 3)) # the first two: [(1, {'at': 1}), (2, {'at': 2})]
list(.(None, 2)) # everything below: [(1, {'at': 1})]
list(.(2, None)) # everything from there up: [(2, {'at': 2}), (3, {'at': 3})]
Prefix scans work on strings, bytes, and tuple keys:
# Create a "logs" collection
logs =["logs"]
# Insert documents
["2026-08-01:a"] = {}
["2026-08-02:b"] = {}
["2026-09-01:c"] = {}
[k for k, _ in logs.("2026-08")]
# ['2026-08-01:a', '2026-08-02:b']Models
A collection is plain-dict by default. You can bind a collection to a dataclass or pydantic model and the collection will validate on write and rebuild instances on read.
from dataclasses import dataclass
@dataclass
class User:
age: int
email: str
# Collection is bound to the 'User' dataclass type
users = db.("users",)
# Insert dataclass instances
["gwen"] =(age=44, email="gwen@example.com")
# Fetch a document, returning the data class instance
["gwen"] # User(age=44, email='gwen@example.com')
The model binding lives on the collection handle, so if you read from an anonymous collection handle, then you get back a dict.
["users"]["gwen"] # {'age': 44, 'email': 'gwen@example.com'}Closing
db.()
Or use the database as a context manager, which closes it on exit:
with monadb.("app.db") as db:
["users"]["alice"] = {"age": 30}