CentauroDB Logo
Getting Started

Quick Start

Build a working app with CentauroDB in under 5 minutes — define, store, query, evolve.

This guide takes you from zero to a working CentauroDB application. You'll define a model, store objects, query them with Python and SQL, and see schema evolution in action — all without writing a single migration.

1. Define a model

Every model inherits from CentauroModel and needs a __centauro_name__ — a stable identifier that decouples your Python class name from stored data:

from centaurodb import CentauroModel

class Note(CentauroModel):
    __centauro_name__ = "Note"
    title: str = ""
    body: str = ""
    tag: str = "general"
All fields must have defaults — this is what makes zero-migration schema evolution possible. Old rows without new fields get the default on read. See Model Rules for why.

2. Create an engine and collection

from centaurodb import Engine, Collection

engine = Engine("app.db")           # file-based SQLite
coll = Collection(engine, "app")     # creates the table automatically

That's it — no CREATE TABLE, no connection pooling setup. For in-memory databases, use Engine() or Engine(":memory:").

3. Write objects

note = Note(title="Chiron's teachings", body="Wisdom from Mount Pelion", tag="lore")
coll.write_object(note)

After writing, the object has database metadata:

print(note.row.id)          # 1
print(note.row.name)        # "Note"
print(note.row.write_time)  # when it was stored

Write a few more so we have data to query:

coll.write_objects([
    Note(title="The Golden Fleece", body="Guarded by a sleepless dragon", tag="quest"),
    Note(title="Labyrinth blueprint", body="Thread from Ariadne required", tag="quest"),
    Note(title="Herbs of Pelion", body="Centaur remedies for battle wounds", tag="lore"),
])

4. Read objects

# By id
loaded = coll.read_object_by_id(1, Note)
print(loaded.title)  # "Chiron's teachings"

# Latest note
latest = coll.read_latest_object(Note)
print(latest.title)  # "Herbs of Pelion"

# All notes
all_notes = coll.read_objects(Note)
print(len(all_notes))  # 4

5. Query with the field DSL

Filter objects without writing SQL:

# By tag
quests = coll.read_objects(Note.fields.tag == "quest")
print(len(quests))  # 2

# Pattern matching
pelion_notes = coll.read_objects(Note.fields.title.like("%Pelion%"))

# Multiple conditions (AND)
results = coll.read_objects(
    Note.fields.tag == "lore",
    Note.fields.title.like("%Chiron%"),
)

6. Update objects

loaded.body = "Zero migrations, forever!"
coll.update_object(loaded)
# edit_time is updated; write_time is preserved

7. Query with SQL views

Create a SQL view to make your JSON data queryable with standard SQL — connect any BI tool, ORM, or dashboard. The view name is {collection}_view_{name} (here app_view_search). See Choosing a view name for naming conventions.

coll.create_view("search", Note)

df = coll.sql_select("""
    SELECT title, tag
    FROM app_view_search
    WHERE tag = 'quest'
    ORDER BY edit_time DESC
""")
print(df)
# ┌──────────────────────┬───────┐
# │ title                ┆ tag   │
# │ ---                  ┆ ---   │
# │ str                  ┆ str   │
# ╞══════════════════════╪═══════╡
# │ Labyrinth blueprint  ┆ quest │
# │ The Golden Fleece    ┆ quest │
# └──────────────────────┴───────┘

Speed up filtered queries by adding an index on the fields you filter on:

coll.create_index("tag")
Indexes live on the objects table, not on views — they are fully independent. See Indexing fields for performance for details.

8. Evolve your schema

Now add a priority field — no migration file, no ALTER TABLE:

class Note(CentauroModel):
    __centauro_name__ = "Note"
    title: str = ""
    body: str = ""
    tag: str = "general"
    priority: int = 0       # new field — old rows get 0 on read

# Old data loads fine
old_note = coll.read_object_by_id(1, Note)
print(old_note.priority)  # 0 — the default

Refresh the view to pick up the new column:

coll.refresh_view("search", Note)

Full example

from centaurodb import CentauroModel, Collection, Engine

class Note(CentauroModel):
    __centauro_name__ = "Note"
    title: str = ""
    body: str = ""
    tag: str = "general"
    priority: int = 0

engine = Engine("app.db")
coll = Collection(engine, "app")

# Write
coll.write_object(Note(title="Chiron's teachings", body="Wisdom from Pelion", tag="lore", priority=1))
coll.write_object(Note(title="The Golden Fleece", body="Guarded by a dragon", tag="quest"))

# Create a SQL view (virtual — reads live data from the table)
coll.create_view("search", Note)

# Indexes live on the table, independent of the view
coll.create_index("tag")
coll.create_index("priority")

# Query with Python
lore = coll.read_objects(Note.fields.tag == "lore")

# Query with SQL
df = coll.sql_select(
    "SELECT title FROM app_view_search WHERE priority > 0"
)

Next steps

Models

Understand CentauroModel rules and choose between regular models and time-series models.

Collections

Master CRUD operations, batch writes, and the full query DSL with like, is_in, and OrGroup.

SQL Views

Create indexed views, multi-model union views, and query with standard SQL.

Schema Evolution

See how adding, removing, and renaming fields works without migrations.
Ready for production? Check the Performance Guide for index tuning, and the PostgreSQL guide for deploying with a server-grade backend.