Surreal ORM Lite
Surreal ORM Lite is a lightweight, Django-style ORM for SurrealDB that uses the official SurrealDB Python SDK. It provides a simple and intuitive interface for database operations with full async support and Pydantic validation.
- Official SDK only: built on
surrealdb[pydantic], no custom protocol, few dependencies. - Two server lines: the same code runs on SurrealDB 2.x and 3.x, and on the SDK's in-process engine
(
mem://,surrealkv://) for tests and notebooks. - Django-style queries:
filter(age__gte=18),Qobjects,order_by("-age"), aggregations, subqueries. - SurrealDB-native: graph relations and typed edges, live queries, change feeds, time travel, full-text, vector and hybrid search, events, views and schema DDL.
- Tooling: migrations, a
surreal-orm-litecommand line, schema introspection, test factories and a pytest plugin.
Documentation: user guide · changelog · roadmap · examples
Installation
pip install surreal-orm-lite
# or
uv add surreal-orm-lite
| Dependency | Version |
|---|---|
| Python | 3.11+ (tested on 3.11 to 3.15) |
| SurrealDB | 2.6.x / 2.7.x or 3.2.x / 3.3.x, or the SDK's embedded engine |
| Official SDK | surrealdb[pydantic]>=2.0.0,<3.0.0 |
| Pydantic | >=2.13.4 |
Quick start
import asyncio
from pydantic import Field
from surreal_orm_lite import BaseSurrealModel, Q, SurrealDBConnectionManager
class User(BaseSurrealModel):
id: str | None = None
name: str = Field(..., max_length=100)
email: str
age: int = Field(..., ge=0)
async def main() -> None:
# A server URL (ws://localhost:8000/rpc, http://localhost:8000) or an in-process engine (mem://).
SurrealDBConnectionManager.set_connection(
url="http://localhost:8000", user="root", password="root", namespace="app", database="app"
)
alice = await User(id="alice", name="Alice", email="alice@example.com", age=30).save()
await User(id="bob", name="Bob", email="bob@example.com", age=17).save()
adults = await User.objects().filter(age__gte=18).order_by("-age").exec()
a_or_minor = await User.objects().filter(Q(name__startswith="A") | Q(age__lt=18)).exec()
average = await User.objects().avg("age")
await alice.merge(age=31) # partial update
await alice.delete()
print(adults, a_or_minor, average)
asyncio.run(main())
The getting started guide walks through it, and the querying guide lists every QuerySet method and filter lookup.
Documentation
| Guide | What it covers |
|---|---|
| Getting started | Requirements, installation, connection, a first model and CRUD |
| Models | Primary keys, table names, server-side values, computed fields, field aliases |
| Field types | Datetimes, durations, decimals, sets, ranges, record links, geospatial fields |
| Querying | QuerySet methods, filter lookups, Q objects, FETCH, aggregations, time travel, subqueries, query cache |
| Writing data | Bulk operations, signals, transactions, upserts, patches, retry on conflict |
| Relations and graph | Graph relations, typed edges, TYPE RELATION constraints |
| Stored functions and events | call_function(), DEFINE EVENT and DEFINE FUNCTION from Python |
| Authentication | signin / signup, record access, AuthenticatedUserMixin |
| Live queries and change feeds | Live queries, typed streams, auto-resubscribe, change feeds |
| Connections | The connection manager, event loops, several databases |
| Embedded engine | mem:// and surrealkv:// in-process databases, test fixtures |
| Schema and DDL | Schema introspection, materialized views, table DDL and permissions |
| Search | Full-text (BM25), vector (KNN, HNSW) and hybrid search |
| Migrations | makemigrations(), operations, MigrationExecutor |
| Command line | surreal-orm-lite: migrate, rollback, inspectdb, schemadiff, shell |
| Testing | ModelFactory, Faker and the pytest plugin |
| Compatibility | Tested versions and every behaviour that differs between SurrealDB 2.x, 3.x and the embedded engine |
The documentation index lists every section of the guides.
Using with AI assistants
The guide for AI coding assistants
gives an assistant such as Claude Code the idioms, the 2.x/3.x differences and the common mistakes in one page,
each example checked by the test suite. Download it into your project, then add the line @docs/surreal-orm-lite.md
to your CLAUDE.md to import it:
curl -fsSL -o docs/surreal-orm-lite.md https://raw.githubusercontent.com/EulogySnowfall/SurrealDB-ORM-lite/main/docs/ai/CLAUDE.md
Tools that read the llms.txt convention find every guide listed there.
Features
| Feature | Status |
|---|---|
| Async/await support | ✅ |
| Pydantic validation | ✅ |
| CRUD operations | ✅ |
| QuerySet with filters | ✅ |
| Django-style lookups | ✅ |
| Custom primary keys | ✅ |
| HTTP connections | ✅ |
| WebSocket connections | ✅ |
| Aggregations | ✅ |
| GROUP BY | ✅ |
| Model Signals | ✅ |
| Raw SurrealQL queries | ✅ |
| Q Objects (OR/AND/NOT) | ✅ |
| Parameterized filters | ✅ |
| Bulk operations | ✅ |
-field ordering |
✅ |
| Relations & Graph | ✅ |
| FETCH clause | ✅ |
Transactions (tx=) |
✅ |
| upsert / get_or_create | ✅ |
| patch / atomic ops | ✅ |
| Retry on conflict | ✅ |
| Server-side functions | ✅ |
| Computed fields | ✅ |
Stored fn:: calls |
✅ |
| JWT / record auth | ✅ |
| Model-level auth mixin | ✅ |
| Field aliases & DX | ✅ |
| Live queries (raw) | ✅ |
| Typed live queries | ✅ |
| Live auto-resubscribe | ✅ |
| Change feeds (CDC) | ✅ |
Typed edges (insert_relation) |
✅ |
| Custom table name | ✅ |
| Rich field types (datetime, date, duration, decimal, uuid, bytes, set, range) | ✅ |
| Geospatial fields (nearby, distance, spatial lookups) | ✅ |
| Embedded engine (mem://, surrealkv://) & test fixtures | ✅ |
Time travel (as_of(), versioned storage) |
✅ |
Subqueries (Subquery, a QuerySet as a filter value) |
✅ |
Query cache (cache(), TTL, invalidated by ORM writes) |
✅ |
Multiple databases (named connections, using()) |
✅ |
Schema introspection (DatabaseIntrospector, generate_models_from_db()) |
✅ |
Server-side events & function DDL (Event, define_function()) |
✅ |
Materialized views (view_query, define_view(), read-only) |
✅ |
Relation constraints (relation_in, define_relation(), TYPE RELATION) |
✅ |
Model table DDL (define_table(), schema_mode, permissions) |
✅ |
Full-text search (search(), BM25 score and highlights) |
✅ |
Vector search (similar_to(), KNN, HNSW indexes) |
✅ |
Hybrid search (hybrid_search(), Reciprocal Rank Fusion) |
✅ |
| Migrations (makemigrations / migrate / rollback) | ✅ |
Command line (surreal-orm-lite: migrations, inspectdb, shell) |
✅ |
Test data factories (ModelFactory, Faker) & pytest plugin |
✅ |
Supported versions
Surreal ORM Lite runs on both SurrealDB release lines, 2.x (2.6 / 2.7) and 3.x (3.2 / 3.3), and on the official SDK's in-process engine. It is tested against SurrealDB v2.7.0 and v3.3.5; SurrealDB 3.1.5 is run as a backward-compatibility check. A few capabilities rely on server features introduced in SurrealDB 3.x: on 2.x the ORM degrades gracefully or says so before sending anything. The compatibility guide lists every tested version and every difference between the two lines and the embedded engine.
SurrealDB-ORM-lite vs SurrealDB-ORM
This project prioritizes stability and compatibility with the official SurrealDB Python SDK. The full SurrealDB-ORM uses a custom SDK for advanced features.
Both projects target the same feature set; the difference is how (official SDK vs custom SDK) and server support. Everything below is on the lite roadmap via the official SDK 2.0 — only the custom-SDK internals stay exclusive to the full ORM; the official SDK's in-process engine (section 26) is lite-only.
| Feature | ORM-lite (official SDK) | ORM (custom SDK) |
|---|---|---|
| Supported SurrealDB | 2.6/2.7 + 3.2/3.3 | 3.x only |
| CRUD & QuerySet | ✅ | ✅ |
| Aggregations & GROUP BY | ✅ | ✅ |
| Model Signals | ✅ | ✅ |
| Bulk Operations | ✅ | ✅ |
| Q Objects (OR/AND/NOT) | ✅ | ✅ |
| Parameterized Filters | ✅ | ✅ |
| Relations & Graph | ✅ (reverse, keyword edge fields, tx= on every write helper: v0.22.0) | ✅ |
| FETCH clause | ✅ | ✅ |
| Transactions (tx=) | ✅ v0.8 (core), v0.9 QS | ✅ |
| Interactive tx (3.x native) | ✅ v0.9 | ✅ |
| upsert / update_or_create | ✅ v0.10.0 | ✅ |
| Atomic field/array operations | ✅ v0.11.0 | ✅ |
| Retry on conflict | ✅ v0.12.0 | ✅ |
| SurrealFunc & server values | ✅ v0.13.0 | ✅ |
| Computed fields | ✅ v0.14.0 | ✅ |
call_function() (fn::) |
✅ v0.15.0 | ✅ |
| JWT Authentication | ✅ v0.16.0 (connection) | ✅ |
| Model auth mixin | ✅ v0.17.0 | ✅ |
| Field Aliases & DX | ✅ v0.18.0 | ✅ |
| Live queries (raw notifs) | ✅ v0.19.0 | ✅ |
| Typed live queries | ✅ v0.20.0 | ✅ |
| Live auto-resubscribe / CDC | ✅ v0.21.0 | ✅ |
| Native typed relations | ✅ v0.22.0 (typed edge models) | ✅ DDL only (TableType.RELATION) |
| Rich field types | ✅ v0.23.0 | ✅ |
| Geospatial Fields | ✅ v0.24.0 | ✅ |
| Embedded engine | ✅ v0.25.0 (mem://, surrealkv://; rocksdb:// #233) | ❌ (HTTP/WebSocket only) |
Time travel (VERSION) |
✅ v0.26.0 (as_of()) |
❌ |
| Subqueries | ✅ v0.27.0 (Subquery, a QuerySet in filter()) |
✅ |
| Query Cache | ✅ v0.28.0 (cache(), QueryCache) |
✅ |
| Multi-database | ✅ v0.29.0 (add_connection(), using()) |
✅ |
| Schema Introspection | ✅ v0.30.0 (DatabaseIntrospector, generate_models_from_db()) |
✅ |
| DEFINE EVENT | ✅ v0.31.0 (Event, define_events(), ASYNC on 3.x) |
✅ migrations (DefineEvent) |
define_function() (DDL) |
✅ v0.31.0 | ❌ |
| Materialized views | ✅ v0.32.0 (view_query, define_view()) |
✅ |
| TYPE RELATION enforcement | ✅ v0.33.0 (relation_in, define_relation()) |
✅ DDL (TableType.RELATION, migrations) |
| Model table DDL | ✅ v0.34.0 (define_table()) |
✅ |
| Full-Text Search | ✅ v0.35.0 (search()) |
✅ |
| Vector Search (KNN/HNSW) | ✅ v0.36.0 (similar_to()) |
✅ |
| Hybrid Search (RRF) | ✅ v0.37.0 (hybrid_search()) |
✅ |
| Migrations & CLI | ✅ v0.38.0 (migrations), ✅ v0.39.0 (CLI) | ✅ |
| Test Fixtures & Factories | ✅ v0.25.0 SurrealFixture; ✅ v0.40.0 factories | ✅ |
| Retry, Logging, Metrics | v0.41.0 | ✅ |
| Connection Pool | post-GA (tentative) | ✅ |
| Custom SDK / CBOR Protocol | ❌ never | ✅ |
Choose ORM-lite if you want the official SDK, minimal dependencies, support for SurrealDB 2.x (2.6 / 2.7) and 3.x (3.2 / 3.3), and a full feature roadmap built entirely on the official SDK.
Choose ORM if you need the custom-SDK internals (CBOR protocol, native connection pool) or those features available today rather than on the roadmap.
- SurrealDB-ORM GitHub: github.com/EulogySnowfall/SurrealDB-ORM
- SurrealDB-ORM PyPI: surrealdb-orm
Project status
Surreal ORM Lite is in alpha (0.x): every Tier 1 to Tier 3 feature of the roadmap has shipped, and the next release, v0.41.0, opens the beta phase (API freeze and hardening) on the way to GA as v2.0.0, numbered after the official SDK 2.0. The release overview lists every release, and docs/ROADMAP.md details each one.
Contributing
Contributions are welcome: see the contributing guide. Report a vulnerability as the security policy describes, not in a public issue.
License
MIT License - see LICENSE for details.
Author
Yannick Croteau GitHub: @EulogySnowfall
Related Projects
- SurrealDB - The database
- surrealdb.py - Official Python SDK
- SurrealDB-ORM - Full-featured ORM with custom SDK
Metadata
Release files for surreal-orm-lite 0.40.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| surreal_orm_lite-0.40.2.tar.gz | 727.1 kB | With provenance | Details for surreal_orm_lite-0.40.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| surreal_orm_lite-0.40.2-py3-none-any.whl | Python 3 | none | any | Details for surreal_orm_lite-0.40.2-py3-none-any.whl |
Total release size: 1.4 MB
Release files / surreal_orm_lite-0.40.2.tar.gz
| Download URL | surreal_orm_lite-0.40.2.tar.gz |
|---|---|
| Size | 727.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
72e306902b2b8212553f4d2028f93daf33a2f5c3478ccdf43184c7dc02edd2dc
|
|
BLAKE2b-256 checksum How to use checksums |
6e63938a806f895897eb84bd2b99e036bcd9d0bc2aa599f24b638f60047a64fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logRelease files / surreal_orm_lite-0.40.2-py3-none-any.whl
| Download URL | surreal_orm_lite-0.40.2-py3-none-any.whl |
|---|---|
| Size | 657.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b464231e7fe857ecf98e09a7dd3e2c505ba79a03a6bfa7ff5d8be283d1390cf7
|
|
BLAKE2b-256 checksum How to use checksums |
8436d5c168bec2433e57b957efb651e3895ce0e8797af7dfea1f3f503067f433
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logSecurity for surreal-orm-lite 0.40.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for surreal_orm_lite-0.40.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.