User Guide
Everything you need to install, configure, and build with Montycat — from getting started to governance, advanced operations, and security.
Schema
What is Schema?
Montycat is a NoSQL database with a flexible data mesh architecture.
It offers a high degree of flexibility: you can work with schema definitions anywhere along the spectrum between a simple key-value store and a strict SQL-like engine.
- No schema at all;
- Works like most NoSQL databases and key-value stores;
- You can store strings, integers, floats, arrays, key-value pairs, and other data types without restrictions.
Why Use Schemas?
- A schema is optional but highly recommended to keep data well-structured and organized — especially in microservice architectures where multiple services interact with Montycat.
Each keyspace in Montycat supports multiple schemas (both enforced and non-enforced) and keeps track of them transparently. - The base Schema class defines a structured schema for records stored inside a Montycat Keyspace.
A schema describes the shape of the data: what fields exist, their types, and their intended usage.
This ensures records remain consistent, strongly typed, and self-describing inside the database.
Note for Rust Client: Rust Client uses Rust's native structs and derives RuntimeSchema to detect field types at runtime and enforce schemas.
from montycat import Schema
class EmployeesSchema(Schema):
username: string
location: string
age: numberSchema enforcement
Schema enforcement brings SQL-like validation to Montycat.
When a schema is enforced, Montycat validates field names and types on every insert and update.
A schema can only be enforced if there are no records (keys) associated with it.
Once enforced, it cannot be modified — but it can be removed if unused.
Both in-memory and persistent keyspaces support schema enforcement.
Schema enforcement brings SQL-like validation to Montycat.
Note for JavaScript & TypeScript: Since these languages lack runtime type checks for class fields, you have to define a metadata object inside your schema class. This transmits field names and types to Montycat for enforcement.
Supported metadata types: String, Number, Boolean, Array, Object, Pointer, Timestamp.
Important: You have to define a metadata object inside your schema class. No complex types such as TypeScript specific types or complex generics are supported.
Strating from version 1.1.1 Montycat and all the clients support nullable values in schema fields when schema enforcement is enabled at the database level.
This enhancement allows you to define fields that can explicitly accept null values, providing greater flexibility in data modeling while maintaining the benefits of schema enforcement. In Python and Rust the feature is supported by default, while in JavaScript and TypeScript you will need to add a special property to the field metadata definition to indicate that the field is nullable.
from montycat import Schema
from keyspaces import Employees #keyspaces.py
class EmployeesSchema(Schema):
username: string
location: string | None
age: number
res = Employees.enforce_schema(EmployeesSchema)
# {"status": True, "payload": None, "error": None}Remove enforced schema
An enforced schema cannot be altered, but it can be removed if no records exist under that schema.
If records are present, removal will be rejected to prevent breaking data consistency.
from keyspaces import Employees #keyspaces.py
from shemas import EmployeesSchema #schemas.py
res = await Employees.remove_enforced_schema(EmployeesSchema)
# {"status": True, "payload": None, "error": None}Schemas preview
Montycat allows you to inspect all schemas associated with a keyspace.
This provides visibility into which schemas are defined and/or enforced, helping you manage multiple schema versions or client-side definitions.
from keyspaces import Employees #keyspaces.py
res = await Employees.list_all_schemas_in_keyspace()
# {"status": True, "payload": {"schemas": [...], "enforced": {...}}, "error": None}Schemas lookup
You can lookup values and keys by schema:
from keyspaces import Employees #keyspaces.py
from schemas import EmployeesSchema #schemas.py
res1 = await Employees.lookup_values_where(
age = 21,
username = "Name",
schema = EmployeesSchema
)
# {"status": True, "payload": [{"username": "Name", "location": "Location", "age": 21}], "error": None}
res2 = await Employees.lookup_keys_where(
age = 21,
username = "Name",
schema = EmployeesSchema
)
# {"status": True, "payload": ["128222336824100726154851618391811195396"], "error": None}