Core Concepts¶
This page gives you the mental model for ApexBase before you dive into the API reference.
Database Root¶
An ApexClient opens a root directory:
The root directory contains the default database and any named databases. ApexBase stores each table as a .apex file.
Databases¶
ApexBase supports multiple isolated databases under one root directory. The default database maps to the root directory. Named databases live in subdirectories.
client.use_database("analytics")
client.use(database="analytics", table="events")
print(client.list_databases())
print(client.current_database)
SQL can refer to another database with database.table syntax:
client.execute("""
SELECT u.name, e.event
FROM default.users u
JOIN analytics.events e ON u.id = e.user_id
""")
Tables¶
Tables are explicit. Create or select a table before using table-scoped methods such as store(), retrieve_all(), and list_fields().
You can also create tables with SQL:
Schemas¶
You may let ApexBase infer column types from the first write, or provide a schema up front for clearer contracts and faster bulk loading.
client.create_table("orders", schema={
"order_id": "int64",
"customer": "string",
"total": "float64",
"paid": "bool",
})
Records And Columns¶
ApexBase accepts row-oriented dictionaries, lists of dictionaries, and columnar dictionaries. For bulk ingest, columnar data is usually the fastest path.
client.store({"name": "Alice", "age": 30})
client.store([
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35},
])
client.store({
"name": ["Diana", "Eve"],
"age": [28, 41],
})
Every stored row has an internal _id. SQL hides _id unless you request it explicitly.
ResultView¶
Queries return a ResultView, which can convert to Python-native rows or columnar DataFrame formats.
result = client.execute("SELECT * FROM users")
rows = result.to_dict()
pandas_df = result.to_pandas()
polars_df = result.to_polars()
arrow_table = result.to_arrow()
Use ResultView when you want to move smoothly between SQL, Python lists, Pandas, Polars, and PyArrow.
Durability¶
Durability is configured when opening the client:
| Mode | Best for | Behavior |
|---|---|---|
fast |
Local analytics, scratch data, benchmarks | Prioritizes throughput |
safe |
Application data with balanced speed and safety | Synchronous writes |
max |
Highest crash safety | Fsync on each write |
Interfaces¶
The same storage engine can be reached through several interfaces:
- Python API for embedded applications and notebooks.
- Rust embedded API for native Rust applications.
- PostgreSQL Wire server for SQL clients and database tools.
- Arrow Flight server for high-throughput columnar result streaming.
Start with the Python API unless you already know you need a wire protocol or Rust integration.