Query Building and Execution

This module provides query building and execution capabilities with Django-style filtering and chaining operations.

QuerySet Classes

class surrealengine.query.base.QuerySet(document_class, connection)[source]

Bases: BaseQuerySet

Query builder for SurrealDB.

This class provides a query builder for document classes with a predefined schema. It extends BaseQuerySet to provide methods for querying and manipulating documents of a specific document class.

document_class

The document class to query

connection

The database connection to use for queries

__init__(document_class, connection)[source]

Initialize a new QuerySet.

Parameters:
  • document_class (Type) – The document class to query

  • connection (Any) – The database connection to use for queries

traverse(path, max_depth=None, unique=True)[source]

Configure a graph traversal for this query.

Parameters:
  • path (str) – Arrow path segment(s), e.g. “->likes->user” or “<-follows”.

  • max_depth (int | None) – Optional bound for depth. For simple single-edge paths we will repeat the path up to max_depth. For complex paths this is ignored and the path is used as-is. This is a pragmatic workaround until SurrealQL exposes native depth quantifiers in arrow paths.

  • unique (bool) – When True, deduplicate results via GROUP BY id to avoid duplicate rows.

Returns:

A cloned QuerySet configured with traversal.

Return type:

QuerySet

shortest_path(src, dst, edge)[source]

Helper for shortest path queries (if supported by SurrealDB).

Note: As of now, SurrealDB does not expose a stable built-in shortest path function in SurrealQL. This method prepares a placeholder raw condition to document the limitation. If SurrealDB adds support, this can be updated to emit the proper function call.

async live(where=None, action=None, *, retry_limit=3, initial_delay=0.5, backoff=2.0)[source]

Subscribe to changes on this table via LIVE queries as an async generator.

This method provides real-time updates for table changes using SurrealDB’s LIVE query functionality. It returns LiveEvent objects for each change (CREATE, UPDATE, DELETE) that occurs on the table.

The underlying implementation uses the surrealdb Async client (websocket). If the current connection uses a connection pool client which does not support LIVE, a NotImplementedError is raised.

Parameters:
  • where (Q | dict | None) – Optional filter (Q or dict) applied client-side to incoming events. Only events matching this filter will be yielded.

  • action (str | List[str] | None) – Optional action filter (‘CREATE’, ‘UPDATE’, ‘DELETE’) or list of actions. Use this to subscribe to specific event types only.

  • retry_limit (int) – Number of times to retry subscription on transient errors (default: 3).

  • initial_delay (float) – Initial backoff delay in seconds (default: 0.5).

  • backoff (float) – Multiplier for exponential backoff (default: 2.0).

Yields:

LiveEvent

Typed event objects with the following attributes:
  • action: Event type (CREATE, UPDATE, DELETE)

  • data: Dictionary containing the document fields

  • ts: Optional timestamp of the event

  • id: Optional RecordID of the affected document

Raises:

NotImplementedError – If the active connection does not support LIVE queries (e.g., when using connection pooling).

Example:

# Subscribe to all user creation events
async for evt in User.objects.live(action="CREATE"):
    print(f"New user: {evt.id}")
    print(f"Data: {evt.data}")

# Filter for specific conditions
async for evt in User.objects.live(where={"status": "active"}, action=["CREATE", "UPDATE"]):
    if evt.is_create:
        print(f"Active user created: {evt.id}")
    elif evt.is_update:
        print(f"Active user updated: {evt.id}")
async join(field_name, target_fields=None, dereference=True, dereference_depth=1)[source]

Perform a JOIN-like operation on a reference field using FETCH.

This method performs a JOIN-like operation on a reference field by using SurrealDB’s FETCH clause to efficiently resolve references in a single query.

Parameters:
  • field_name (str) – The name of the reference field to join on

  • target_fields (List[str] | None) – Optional list of fields to select from the target document

  • dereference (bool) – Whether to dereference references in the joined documents (default: True)

  • dereference_depth (int) – Maximum depth of reference resolution (default: 1)

Returns:

List of documents with joined data

Raises:

ValueError – If the field is not a ReferenceField

Return type:

List[Any]

join_sync(field_name, target_fields=None, dereference=True, dereference_depth=1)[source]

Perform a JOIN-like operation on a reference field synchronously using FETCH.

This method performs a JOIN-like operation on a reference field by using SurrealDB’s FETCH clause to efficiently resolve references in a single query.

Parameters:
  • field_name (str) – The name of the reference field to join on

  • target_fields (List[str] | None) – Optional list of fields to select from the target document

  • dereference (bool) – Whether to dereference references in the joined documents (default: True)

  • dereference_depth (int) – Maximum depth of reference resolution (default: 1)

Returns:

List of documents with joined data

Raises:

ValueError – If the field is not a ReferenceField

Return type:

List[Any]

async all(dereference=False)[source]

Execute the query and return all results asynchronously.

This method builds and executes the query, then converts the results to instances of the document class.

Parameters:

dereference (bool) – Whether to dereference references (default: False)

Returns:

List of document instances

Return type:

List[Any]

all_sync(dereference=False)[source]

Execute the query and return all results synchronously.

This method builds and executes the query, then converts the results to instances of the document class.

Parameters:

dereference (bool) – Whether to dereference references (default: False)

Returns:

List of document instances

Return type:

List[Any]

async count()[source]

Count documents matching the query asynchronously.

This method builds and executes a count query to count the number of documents matching the query.

Returns:

Number of matching documents

Return type:

int

count_sync()[source]

Count documents matching the query synchronously.

This method builds and executes a count query to count the number of documents matching the query.

Returns:

Number of matching documents

Return type:

int

async get(dereference=False, **kwargs)[source]

Get a single document matching the query asynchronously.

This method applies filters and ensures that exactly one document is returned.

Parameters:
  • dereference (bool) – Whether to dereference references (default: False)

  • **kwargs (Any) – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

get_sync(dereference=False, **kwargs)[source]

Get a single document matching the query synchronously.

This method applies filters and ensures that exactly one document is returned.

Parameters:
  • dereference (bool) – Whether to dereference references (default: False)

  • **kwargs (Any) – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

async create(**kwargs)[source]

Create a new document asynchronously.

This method creates a new document with the given field values.

Parameters:

**kwargs (Any) – Field names and values for the new document

Returns:

The created document

Return type:

Any

create_sync(**kwargs)[source]

Create a new document synchronously.

This method creates a new document with the given field values.

Parameters:

**kwargs (Any) – Field names and values for the new document

Returns:

The created document

Return type:

Any

async update(returning=None, **kwargs)[source]

Update documents matching the query asynchronously with performance optimizations.

This method updates documents matching the query with the given field values. Uses direct record access for bulk ID operations for better performance.

Parameters:

**kwargs (Any) – Field names and values to update

Returns:

List of updated documents

Return type:

List[Any]

update_sync(returning=None, **kwargs)[source]

Update documents matching the query synchronously with performance optimizations.

This method updates documents matching the query with the given field values. Uses direct record access for bulk ID operations for better performance.

Parameters:

**kwargs (Any) – Field names and values to update

Returns:

List of updated documents

Return type:

List[Any]

async delete()[source]

Delete documents matching the query asynchronously with performance optimizations.

This method deletes documents matching the query. Uses direct record access for bulk ID operations for better performance.

Returns:

Number of deleted documents

Return type:

int

delete_sync()[source]

Delete documents matching the query synchronously with performance optimizations.

This method deletes documents matching the query. Uses direct record access for bulk ID operations for better performance.

Returns:

Number of deleted documents

Return type:

int

async bulk_create(documents, batch_size=1000, validate=True, return_documents=True)[source]

Create multiple documents in a single operation asynchronously.

This method creates multiple documents in a single operation, processing them in batches for better performance. It can optionally validate the documents and return the created documents.

Parameters:
  • documents (List[Any]) – List of Document instances to create

  • batch_size (int) – Number of documents per batch (default: 1000)

  • validate (bool) – Whether to validate documents (default: True)

  • return_documents (bool) – Whether to return created documents (default: True)

Returns:

List of created documents with their IDs set if return_documents=True, otherwise returns the count of created documents

Return type:

List[Any] | int

bulk_create_sync(documents, batch_size=1000, validate=True, return_documents=True)[source]

Create multiple documents in a single operation synchronously.

This method creates multiple documents in a single operation, processing them in batches for better performance. It can optionally validate the documents and return the created documents.

Parameters:
  • documents (List[Any]) – List of Document instances to create

  • batch_size (int) – Number of documents per batch (default: 1000)

  • validate (bool) – Whether to validate documents (default: True)

  • return_documents (bool) – Whether to return created documents (default: True)

Returns:

List of created documents with their IDs set if return_documents=True, otherwise returns the count of created documents

Return type:

List[Any] | int

async explain(full=False)[source]

Get query execution plan for performance analysis.

This method appends EXPLAIN to the query to show how SurrealDB will execute it, helping identify performance bottlenecks.

Parameters:

full (bool) – Whether to include full explanation including execution trace (default: False)

Returns:

List of execution plan steps with details

Return type:

List[Dict[str, Any]]

Example

plan = await User.objects.filter(age__lt=18).explain() print(f”Query will use: {plan[0][‘operation’]}”)

explain_sync(full=False)[source]

Get query execution plan for performance analysis synchronously.

Parameters:

full (bool) – Whether to include full explanation including execution trace (default: False)

Returns:

List of execution plan steps with details

Return type:

List[Dict[str, Any]]

suggest_indexes()[source]

Suggest indexes based on current query patterns.

Analyzes the current query conditions and suggests optimal indexes that could improve performance.

Returns:

List of suggested DEFINE INDEX statements

Return type:

List[str]

Example:

suggestions = User.objects.filter(age__lt=18, city="NYC").suggest_indexes()
for suggestion in suggestions:
    print(f"Consider: {suggestion}")
class surrealengine.query.relation.RelationQuerySet(from_document, connection, relation=None)[source]

Bases: object

Query set specifically for graph relations.

This class provides methods for querying and manipulating graph relations between documents in the database. It allows creating, retrieving, updating, and deleting relations between documents.

from_document

The document class the relation is from

connection

The database connection to use for queries

relation

The name of the relation

query_parts

List of query parts

__init__(from_document, connection, relation=None)[source]

Initialize a new RelationQuerySet.

Parameters:
  • from_document (Type) – The document class the relation is from

  • connection (Any) – The database connection to use for queries

  • relation (str | None) – The name of the relation

async relate(from_instance, to_instance, **attrs)[source]

Create a relation between two instances asynchronously.

This method creates a relation between two document instances in the database. It constructs a RELATE query with the given relation name and attributes.

Parameters:
  • from_instance (Any) – The instance to create the relation from

  • to_instance (Any) – The instance to create the relation to

  • **attrs (Any) – Attributes to set on the relation

Returns:

The created relation record or None if creation failed

Raises:

ValueError – If either instance is not saved or if no relation name is specified

Return type:

Any | None

relate_sync(from_instance, to_instance, **attrs)[source]

Create a relation between two instances synchronously.

This method creates a relation between two document instances in the database. It constructs a RELATE query with the given relation name and attributes.

Parameters:
  • from_instance (Any) – The instance to create the relation from

  • to_instance (Any) – The instance to create the relation to

  • **attrs (Any) – Attributes to set on the relation

Returns:

The created relation record or None if creation failed

Raises:

ValueError – If either instance is not saved or if no relation name is specified

Return type:

Any | None

Get related documents asynchronously.

This method retrieves documents related to the given instance through the specified relation. It can return either the target documents or the relation records themselves.

Parameters:
  • instance (Any) – The instance to get related documents for

  • target_document (Type | None) – The document class of the target documents (optional)

  • **filters (Any) – Filters to apply to the related documents

Returns:

List of related documents or relation records

Raises:

ValueError – If the instance is not saved or if no relation name is specified

Return type:

List[Any]

Get related documents synchronously.

This method retrieves documents related to the given instance through the specified relation. It can return either the target documents or the relation records themselves.

Parameters:
  • instance (Any) – The instance to get related documents for

  • target_document (Type | None) – The document class of the target documents (optional)

  • **filters (Any) – Filters to apply to the related documents

Returns:

List of related documents or relation records

Raises:

ValueError – If the instance is not saved or if no relation name is specified

Return type:

List[Any]

async update_relation(from_instance, to_instance, **attrs)[source]

Update an existing relation asynchronously.

This method updates an existing relation between two document instances in the database. If the relation doesn’t exist, it creates it.

Parameters:
  • from_instance (Any) – The instance the relation is from

  • to_instance (Any) – The instance the relation is to

  • **attrs (Any) – Attributes to update on the relation

Returns:

The updated relation record or None if update failed

Raises:

ValueError – If either instance is not saved or if no relation name is specified

Return type:

Any | None

update_relation_sync(from_instance, to_instance, **attrs)[source]

Update an existing relation synchronously.

This method updates an existing relation between two document instances in the database. If the relation doesn’t exist, it creates it.

Parameters:
  • from_instance (Any) – The instance the relation is from

  • to_instance (Any) – The instance the relation is to

  • **attrs (Any) – Attributes to update on the relation

Returns:

The updated relation record or None if update failed

Raises:

ValueError – If either instance is not saved or if no relation name is specified

Return type:

Any | None

async delete_relation(from_instance, to_instance=None)[source]

Delete a relation asynchronously.

This method deletes a relation between two document instances in the database. If to_instance is not provided, it deletes all relations from from_instance.

Parameters:
  • from_instance (Any) – The instance the relation is from

  • to_instance (Any | None) – The instance the relation is to (optional)

Returns:

Number of deleted relations

Raises:

ValueError – If from_instance is not saved, if to_instance is provided but not saved, or if no relation name is specified

Return type:

int

delete_relation_sync(from_instance, to_instance=None)[source]

Delete a relation synchronously.

This method deletes a relation between two document instances in the database. If to_instance is not provided, it deletes all relations from from_instance.

Parameters:
  • from_instance (Any) – The instance the relation is from

  • to_instance (Any | None) – The instance the relation is to (optional)

Returns:

Number of deleted relations

Raises:

ValueError – If from_instance is not saved, if to_instance is provided but not saved, or if no relation name is specified

Return type:

int

Base Query Classes

class surrealengine.base_query.BaseQuerySet(connection)[source]

Bases: object

Base query builder for SurrealDB.

This class provides the foundation for building queries in SurrealDB. It includes methods for filtering, limiting, ordering, and retrieving results. Subclasses must implement specific methods like _build_query, all, and count.

connection

The database connection to use for queries

query_parts

List of query conditions (field, operator, value)

limit_value

Maximum number of results to return

start_value

Number of results to skip (for pagination)

order_by_value

Field and direction to order results by

group_by_fields

Fields to group results by

split_fields

Fields to split results by

fetch_fields

Fields to fetch related records for

with_index[source]

Index to use for the query

__init__(connection)[source]

Initialize a new BaseQuerySet.

Parameters:

connection (Any) – The database connection to use for queries

is_async_connection()[source]

Check if the connection is asynchronous.

Returns:

True if the connection is asynchronous, False otherwise

Return type:

bool

filter(query=None, **kwargs)[source]

Add filter conditions to the query with automatic ID optimization.

This method supports both Q objects and Django-style field lookups with double-underscore operators: - field__gt: Greater than - field__lt: Less than - field__gte: Greater than or equal - field__lte: Less than or equal - field__ne: Not equal - field__in: Inside (for arrays) - optimized for ID fields - field__nin: Not inside (for arrays) - field__contains: Contains (for strings or arrays) - field__startswith: Starts with (for strings) - field__endswith: Ends with (for strings) - field__regex: Matches regex pattern (for strings)

PERFORMANCE OPTIMIZATIONS: - id__in automatically uses direct record access syntax - ID range queries (id__gte + id__lte) use range syntax

Parameters:
  • query – Q object or QueryExpression for complex queries

  • **kwargs – Field names and values to filter by

Returns:

A new queryset instance for method chaining

Raises:

ValueError – If an unknown operator is provided

Return type:

BaseQuerySet

only(*fields)[source]

Select only the specified fields.

This method sets the fields to be selected in the query. It automatically includes the ‘id’ field.

Parameters:

*fields (str) – Field names to select

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

omit(*fields)[source]

Exclude specific fields from the results.

Parameters:

*fields (str) – Field names to exclude

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

limit(value)[source]

Set the maximum number of results to return.

Parameters:

value (int) – Maximum number of results

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

start(value)[source]

Set the number of results to skip (for pagination).

Parameters:

value (int) – Number of results to skip

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

order_by(field, direction='ASC')[source]

Set the field and direction to order results by.

Parameters:
  • field (str) – Field name to order by

  • direction (str) – Direction to order by (‘ASC’ or ‘DESC’)

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

group_by(*fields, all=False)[source]

Group the results by the specified fields or group all.

This method sets the fields to group the results by using the GROUP BY clause.

Parameters:
  • *fields (str) – Field names to group by

  • all (bool) – If True, use GROUP ALL (SurrealDB v2.0.0+)

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

split(*fields)[source]

Split the results by the specified fields.

This method sets the fields to split the results by using the SPLIT clause.

Parameters:

*fields (str) – Field names to split by

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

fetch(*fields)[source]

Fetch related records for the specified fields.

This method sets the fields to fetch related records for using the FETCH clause.

Parameters:

*fields (str) – Field names to fetch related records for

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

get_many(ids)[source]

Get multiple records by IDs using optimized direct record access.

This method uses SurrealDB’s direct record selection syntax for better performance compared to WHERE clause filtering.

Parameters:

ids (List[str | Any]) – List of record IDs (can be strings or other ID types)

Returns:

The query set instance configured for direct record access

Return type:

BaseQuerySet

Example

# Efficient: SELECT * FROM users:1, users:2, users:3 users = await User.objects.get_many([1, 2, 3]).all() users = await User.objects.get_many([‘users:1’, ‘users:2’]).all()

get_range(start_id, end_id, inclusive=True)[source]

Get a range of records by ID using optimized range syntax.

This method uses SurrealDB’s range selection syntax for better performance compared to WHERE clause filtering.

Parameters:
  • start_id (str | Any) – Starting ID of the range

  • end_id (str | Any) – Ending ID of the range

  • inclusive (bool) – Whether the range is inclusive (default: True)

Returns:

The query set instance configured for range access

Return type:

BaseQuerySet

Example

# Efficient: SELECT * FROM users:100..=200 users = await User.objects.get_range(100, 200).all() users = await User.objects.get_range(‘users:100’, ‘users:200’, inclusive=False).all()

with_index(index)[source]

Use the specified index for the query.

This method sets the index to use for the query using the WITH clause.

Parameters:

index (str) – Name of the index to use

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

no_index()[source]

Do not use any index for the query.

This method adds the WITH NOINDEX clause to the query.

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

timeout(duration)[source]

Set a timeout for the query execution.

Parameters:

duration (str) – Duration string (e.g. “5s”, “1m”)

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

tempfiles(value=True)[source]

Enable or disable using temporary files for large queries.

Parameters:

value (bool) – Whether to use tempfiles (default: True)

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

with_explain(full=False)[source]

Explain the query execution plan (builder pattern).

Parameters:

full (bool) – Whether to include full explanation including execution trace (default: False)

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

use_direct_access()[source]

Mark this queryset to prefer direct record access when possible.

This method sets a preference for using direct record access patterns over WHERE clause filtering for better performance.

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

async all()[source]

Execute the query and return all results asynchronously.

This method must be implemented by subclasses to execute the query and return the results.

Returns:

List of results

Raises:

NotImplementedError – If not implemented by a subclass

Return type:

List[Any]

all_sync()[source]

Execute the query and return all results synchronously.

This method must be implemented by subclasses to execute the query and return the results.

Returns:

List of results

Raises:

NotImplementedError – If not implemented by a subclass

Return type:

List[Any]

async first()[source]

Execute the query and return the first result asynchronously.

This method limits the query to one result and returns the first item or None if no results are found.

Returns:

The first result or None if no results

Return type:

Any | None

first_sync()[source]

Execute the query and return the first result synchronously.

This method limits the query to one result and returns the first item or None if no results are found.

Returns:

The first result or None if no results

Return type:

Any | None

async get(**kwargs)[source]

Get a single document matching the query asynchronously.

This method applies filters and ensures that exactly one document is returned. For ID-based lookups, it uses direct record syntax instead of WHERE clause.

Parameters:

**kwargs – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

get_sync(**kwargs)[source]

Get a single document matching the query synchronously.

This method applies filters and ensures that exactly one document is returned. For ID-based lookups, it uses direct record syntax instead of WHERE clause.

Parameters:

**kwargs – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

async count()[source]

Count documents matching the query asynchronously.

This method must be implemented by subclasses to count the number of documents matching the query.

Returns:

Number of matching documents

Raises:

NotImplementedError – If not implemented by a subclass

Return type:

int

count_sync()[source]

Count documents matching the query synchronously.

This method must be implemented by subclasses to count the number of documents matching the query.

Returns:

Number of matching documents

Raises:

NotImplementedError – If not implemented by a subclass

Return type:

int

__await__()[source]

Make the queryset awaitable.

This method allows the queryset to be used with the await keyword, which will execute the query and return all results.

Returns:

Awaitable that resolves to the query results

page(number, size)[source]

Set pagination parameters using page number and size.

This method calculates the appropriate LIMIT and START values based on the page number and size, providing a more convenient way to paginate results.

Parameters:
  • number (int) – Page number (1-based, first page is 1)

  • size (int) – Number of items per page

Returns:

The query set instance for method chaining

Return type:

BaseQuerySet

async paginate(page, per_page)[source]

Get a page of results with pagination metadata asynchronously.

This method gets a page of results along with metadata about the pagination, such as the total number of items, the number of pages, and whether there are next or previous pages.

Parameters:
  • page (int) – The page number (1-based)

  • per_page (int) – The number of items per page

Returns:

A PaginationResult containing the items and pagination metadata

Return type:

PaginationResult

paginate_sync(page, per_page)[source]

Get a page of results with pagination metadata synchronously.

This method gets a page of results along with metadata about the pagination, such as the total number of items, the number of pages, and whether there are next or previous pages.

Parameters:
  • page (int) – The page number (1-based)

  • per_page (int) – The number of items per page

Returns:

A PaginationResult containing the items and pagination metadata

Return type:

PaginationResult

get_raw_query()[source]

Get the raw query string without executing it.

This method builds and returns the query string without executing it. It can be used to get the raw query for manual execution or debugging.

Returns:

The raw query string

Return type:

str

aggregate()[source]

Create an aggregation pipeline from this query.

This method returns an AggregationPipeline instance that can be used to build and execute complex aggregation queries with multiple stages.

Returns:

An AggregationPipeline instance for building and executing aggregation queries.

Query Descriptors

class surrealengine.query.descriptor.QuerySetDescriptor[source]

Bases: object

Descriptor that provides QuerySet access through Document.objects.

This class is a descriptor that provides access to a QuerySet through the Document.objects attribute. It allows querying documents of a specific document class using the Document.objects attribute.

owner

The document class that owns this descriptor

connection

The database connection to use for queries

__init__()[source]

Initialize a new QuerySetDescriptor.

__get__(obj, owner)[source]

Get the descriptor for the given owner.

This method is called when the descriptor is accessed through an attribute of a class or instance.

Parameters:
  • obj (Any) – The instance the descriptor is accessed through, or None

  • owner (Type) – The class the descriptor is accessed through

Returns:

The descriptor instance

Return type:

QuerySetDescriptor

async __call__(query=None, limit=None, start=None, page=None, **kwargs)[source]

Allow direct filtering through call syntax asynchronously.

This method allows calling the descriptor directly with filters or query objects to query the document class. It supports pagination through limit and start parameters or the page parameter.

Parameters:
  • query – Q object or QueryExpression for complex queries

  • limit (int | None) – Maximum number of results to return (for pagination)

  • start (int | None) – Number of results to skip (for pagination)

  • page (tuple | None) – Tuple of (page_number, page_size) for pagination

  • **kwargs (Any) – Field names and values to filter by

Returns:

List of matching documents

Return type:

List[Any]

call_sync(query=None, limit=None, start=None, page=None, **kwargs)[source]

Allow direct filtering through call syntax synchronously.

This method allows calling the descriptor directly with filters or query objects to query the document class. It supports pagination through limit and start parameters or the page parameter.

Parameters:
  • query – Q object or QueryExpression for complex queries

  • limit (int | None) – Maximum number of results to return (for pagination)

  • start (int | None) – Number of results to skip (for pagination)

  • page (tuple | None) – Tuple of (page_number, page_size) for pagination

  • **kwargs (Any) – Field names and values to filter by

Returns:

List of matching documents

Return type:

List[Any]

async get(**kwargs)[source]

Allow direct get operation asynchronously.

This method allows getting a single document matching the given filters.

Parameters:

**kwargs (Any) – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

get_sync(**kwargs)[source]

Allow direct get operation synchronously.

This method allows getting a single document matching the given filters.

Parameters:

**kwargs (Any) – Field names and values to filter by

Returns:

The matching document

Raises:
Return type:

Any

filter(query=None, **kwargs)[source]

Create a QuerySet with filters using the default async connection.

This method creates a new QuerySet with the given filters using the default async connection.

Parameters:
  • query – Q object or QueryExpression for complex queries

  • **kwargs (Any) – Field names and values to filter by

Returns:

A QuerySet with the given filters

Return type:

QuerySet

filter_sync(query=None, **kwargs)[source]

Create a QuerySet with filters using the default sync connection.

This method creates a new QuerySet with the given filters using the default sync connection.

Parameters:
  • query – Q object or QueryExpression for complex queries

  • **kwargs (Any) – Field names and values to filter by

Returns:

A QuerySet with the given filters

Return type:

QuerySet

limit(value)[source]

Set the maximum number of results to return.

Parameters:

value (int) – Maximum number of results

Returns:

A QuerySet with the limit applied

Return type:

QuerySet

limit_sync(value)[source]

Set the maximum number of results to return using the default sync connection.

Parameters:

value (int) – Maximum number of results

Returns:

A QuerySet with the limit applied

Return type:

QuerySet

start(value)[source]

Set the number of results to skip (for pagination).

Parameters:

value (int) – Number of results to skip

Returns:

A QuerySet with the start applied

Return type:

QuerySet

start_sync(value)[source]

Set the number of results to skip (for pagination) using the default sync connection.

Parameters:

value (int) – Number of results to skip

Returns:

A QuerySet with the start applied

Return type:

QuerySet

order_by(field, direction='ASC')[source]

Set the field and direction to order results by.

Parameters:
  • field (str) – Field name to order by

  • direction (str) – Direction to order by (‘ASC’ or ‘DESC’)

Returns:

A QuerySet with the order by applied

Return type:

QuerySet

order_by_sync(field, direction='ASC')[source]

Set the field and direction to order results by using the default sync connection.

Parameters:
  • field (str) – Field name to order by

  • direction (str) – Direction to order by (‘ASC’ or ‘DESC’)

Returns:

A QuerySet with the order by applied

Return type:

QuerySet

group_by(*fields)[source]

Group the results by the specified fields.

This method sets the fields to group the results by using the GROUP BY clause.

Parameters:

*fields (str) – Field names to group by

Returns:

A QuerySet with the group by applied

Return type:

QuerySet

group_by_sync(*fields)[source]

Group the results by the specified fields using the default sync connection.

This method sets the fields to group the results by using the GROUP BY clause.

Parameters:

*fields (str) – Field names to group by

Returns:

A QuerySet with the group by applied

Return type:

QuerySet

split(*fields)[source]

Split the results by the specified fields.

This method sets the fields to split the results by using the SPLIT clause.

Parameters:

*fields (str) – Field names to split by

Returns:

A QuerySet with the split applied

Return type:

QuerySet

split_sync(*fields)[source]

Split the results by the specified fields using the default sync connection.

This method sets the fields to split the results by using the SPLIT clause.

Parameters:

*fields (str) – Field names to split by

Returns:

A QuerySet with the split applied

Return type:

QuerySet

fetch(*fields)[source]

Fetch related records for the specified fields.

This method sets the fields to fetch related records for using the FETCH clause.

Parameters:

*fields (str) – Field names to fetch related records for

Returns:

A QuerySet with the fetch applied

Return type:

QuerySet

fetch_sync(*fields)[source]

Fetch related records for the specified fields using the default sync connection.

This method sets the fields to fetch related records for using the FETCH clause.

Parameters:

*fields (str) – Field names to fetch related records for

Returns:

A QuerySet with the fetch applied

Return type:

QuerySet

async first()[source]

Get the first result from the query asynchronously.

Returns:

The first matching document or None if no matches

Raises:

DoesNotExist – If no matching document is found

Return type:

Any

first_sync()[source]

Get the first result from the query synchronously.

Returns:

The first matching document or None if no matches

Raises:

DoesNotExist – If no matching document is found

Return type:

Any

page(number, size)[source]

Set pagination parameters using page number and size.

Parameters:
  • number (int) – Page number (1-based, first page is 1)

  • size (int) – Number of items per page

Returns:

A QuerySet with pagination applied

Return type:

QuerySet

page_sync(number, size)[source]

Set pagination parameters using page number and size using the default sync connection.

Parameters:
  • number (int) – Page number (1-based, first page is 1)

  • size (int) – Number of items per page

Returns:

A QuerySet with pagination applied

Return type:

QuerySet

async paginate(page, per_page)[source]

Get a page of results with pagination metadata asynchronously.

This method gets a page of results along with metadata about the pagination, such as the total number of items, the number of pages, and whether there are next or previous pages.

Parameters:
  • page (int) – The page number (1-based)

  • per_page (int) – The number of items per page

Returns:

A PaginationResult containing the items and pagination metadata

Return type:

PaginationResult

paginate_sync(page, per_page)[source]

Get a page of results with pagination metadata synchronously.

This method gets a page of results along with metadata about the pagination, such as the total number of items, the number of pages, and whether there are next or previous pages.

Parameters:
  • page (int) – The page number (1-based)

  • per_page (int) – The number of items per page

Returns:

A PaginationResult containing the items and pagination metadata

Return type:

PaginationResult

aggregate()[source]

Create an aggregation pipeline from this query.

This method returns an AggregationPipeline instance that can be used to build and execute complex aggregation queries with multiple stages.

Returns:

An AggregationPipeline instance for building and executing aggregation queries.

aggregate_sync()[source]

Create an aggregation pipeline from this query using the default sync connection.

This method returns an AggregationPipeline instance that can be used to build and execute complex aggregation queries with multiple stages.

Returns:

An AggregationPipeline instance for building and executing aggregation queries.

async join(field_name, target_fields=None, dereference=True, dereference_depth=1)[source]

Perform a JOIN-like operation on a reference field.

This method performs a JOIN-like operation on a reference field by using SurrealDB’s graph traversal capabilities. It retrieves the referenced documents and replaces the reference IDs with the actual documents.

Parameters:
  • field_name (str) – The name of the reference field to join on

  • target_fields (List[str] | None) – Optional list of fields to select from the target document

  • dereference (bool) – Whether to dereference references in the joined documents (default: True)

  • dereference_depth (int) – Maximum depth of reference resolution (default: 1)

Returns:

List of documents with joined data

Raises:

ValueError – If the field is not a ReferenceField

Return type:

List[Any]

join_sync(field_name, target_fields=None, dereference=True, dereference_depth=1)[source]

Perform a JOIN-like operation on a reference field synchronously.

This method performs a JOIN-like operation on a reference field by using SurrealDB’s graph traversal capabilities. It retrieves the referenced documents and replaces the reference IDs with the actual documents.

Parameters:
  • field_name (str) – The name of the reference field to join on

  • target_fields (List[str] | None) – Optional list of fields to select from the target document

  • dereference (bool) – Whether to dereference references in the joined documents (default: True)

  • dereference_depth (int) – Maximum depth of reference resolution (default: 1)

Returns:

List of documents with joined data

Raises:

ValueError – If the field is not a ReferenceField

Return type:

List[Any]

get_many(ids)[source]

Get multiple records by IDs using optimized direct record access.

This method uses SurrealDB’s direct record selection syntax for better performance compared to WHERE clause filtering.

Parameters:

ids (List[str | Any]) – List of record IDs (can be strings or other ID types)

Returns:

The query set instance configured for direct record access

Return type:

QuerySet

get_many_sync(ids)[source]

Get multiple records by IDs using optimized direct record access synchronously.

Parameters:

ids (List[str | Any]) – List of record IDs (can be strings or other ID types)

Returns:

The query set instance configured for direct record access

Return type:

QuerySet

get_range(start_id, end_id, inclusive=True)[source]

Get a range of records by ID using optimized range syntax.

This method uses SurrealDB’s range selection syntax for better performance compared to WHERE clause filtering.

Parameters:
  • start_id (str | Any) – Starting ID of the range

  • end_id (str | Any) – Ending ID of the range

  • inclusive (bool) – Whether the range is inclusive (default: True)

Returns:

The query set instance configured for range access

Return type:

QuerySet

get_range_sync(start_id, end_id, inclusive=True)[source]

Get a range of records by ID using optimized range syntax synchronously.

Parameters:
  • start_id (str | Any) – Starting ID of the range

  • end_id (str | Any) – Ending ID of the range

  • inclusive (bool) – Whether the range is inclusive (default: True)

Returns:

The query set instance configured for range access

Return type:

QuerySet

async bulk_create(documents, batch_size=1000, validate=True, return_documents=True)[source]

Create multiple documents in a single operation asynchronously.

This method creates multiple documents in a single operation, processing them in batches for better performance.

Parameters:
  • documents (List[Any]) – List of Document instances to create

  • batch_size (int) – Number of documents per batch (default: 1000)

  • validate (bool) – Whether to validate documents (default: True)

  • return_documents (bool) – Whether to return created documents (default: True)

Returns:

List of created documents with their IDs set if return_documents=True, otherwise returns the count of created documents

Return type:

List[Any] | int

bulk_create_sync(documents, batch_size=1000, validate=True, return_documents=True)[source]

Create multiple documents in a single operation synchronously.

Parameters:
  • documents (List[Any]) – List of Document instances to create

  • batch_size (int) – Number of documents per batch (default: 1000)

  • validate (bool) – Whether to validate documents (default: True)

  • return_documents (bool) – Whether to return created documents (default: True)

Returns:

List of created documents with their IDs set if return_documents=True, otherwise returns the count of created documents

Return type:

List[Any] | int

async all()[source]

Execute the query and return all results asynchronously.

Returns:

List of all documents matching any implicit query

Return type:

List[Any]

all_sync()[source]

Execute the query and return all results synchronously.

Returns:

List of all documents matching any implicit query

Return type:

List[Any]

async count()[source]

Count all documents asynchronously.

Returns:

Number of documents

Return type:

int

count_sync()[source]

Count all documents synchronously.

Returns:

Number of documents

Return type:

int

Query Expressions

Query expression system for SurrealEngine

This module provides a query expression system that allows building complex queries programmatically and passing them to objects() and filter() methods.

class surrealengine.query_expressions.Q(**kwargs)[source]

Bases: object

Query expression builder for complex queries.

This class allows building complex query expressions that can be used with filter() and objects() methods.

Examples

Simple query:

>>> q = Q(age__gt=25)
>>> users = User.objects.filter(q).all()  # example

Complex AND/OR queries:

>>> q1 = Q(age__gt=25) & Q(active=True)  # AND condition
>>> active_older_users = User.objects.filter(q1).all()  # example
>>> q2 = Q(age__lt=30) | Q(username="charlie")  # OR condition
>>> users_or = User.objects.filter(q2).all()  # example

Using NOT:

>>> q3 = ~Q(active=True)  # NOT active
>>> inactive_users = User.objects.filter(q3).all()  # example

Raw queries:

>>> q4 = Q.raw("age > 20 AND username CONTAINS 'a'")
>>> users_raw = User.objects.filter(q4).all()  # example

Query operators:

>>> queries = [
...     Q(age__in=[25, 30]),  # IN operator
...     Q(username__startswith="a"),  # STARTSWITH
...     Q(email__contains="example"),  # CONTAINS
...     Q(age__gte=25) & Q(age__lte=35),  # Range
... ]

Using with objects() method:

>>> query = Q(published=True) & Q(views__gt=75)
>>> popular_posts = Post.objects(query)  # example

Combining with additional filters:

>>> base_query = Q(published=True)
>>> high_view_posts = Post.objects(base_query, views__gt=150)  # example
__init__(**kwargs)[source]

Initialize a query expression.

Parameters:

**kwargs – Field filters to include in the query

__and__(other)[source]

Combine with another Q object using AND.

__or__(other)[source]

Combine with another Q object using OR.

__invert__()[source]

Negate this query using NOT.

classmethod raw(query_string)[source]

Create a raw query expression.

Parameters:

query_string (str) – Raw SurrealQL WHERE clause

Returns:

Q object with raw query

Return type:

Q

to_conditions()[source]

Convert this Q object to a list of conditions.

Returns:

List of (field, operator, value) tuples

Return type:

List[tuple]

to_where_clause()[source]

Convert this Q object to a WHERE clause string.

Returns:

WHERE clause string for SurrealQL

Return type:

str

class surrealengine.query_expressions.QueryExpression(where=None)[source]

Bases: object

Higher-level query expression that can include fetch, grouping, etc.

This class provides a more comprehensive query building interface that includes not just WHERE conditions but also FETCH, GROUP BY, etc.

Examples

QueryExpression with FETCH for dereferencing:

>>> expr = QueryExpression(where=Q(published=True)).fetch("author")
>>> posts_with_authors = Post.objects.filter(expr).all()  # example

Complex QueryExpression with multiple clauses:

>>> complex_expr = (QueryExpression(where=Q(active=True))
...                .order_by("age", "DESC")
...                .limit(2))
>>> top_users = User.objects.filter(complex_expr).all()  # example

QueryExpression with grouping:

>>> expr = (QueryExpression(where=Q(published=True))
...         .group_by("category")
...         .order_by("created_at", "DESC"))

QueryExpression with pagination:

>>> expr = (QueryExpression(where=Q(active=True))
...         .order_by("created_at", "DESC")
...         .limit(10)
...         .start(20))  # Skip first 20 records

Combining with fetch for complex relationships:

>>> expr = (QueryExpression(where=Q(type="article"))
...         .fetch("author", "category", "tags")
...         .order_by("published_at", "DESC"))
__init__(where=None)[source]

Initialize a query expression.

Parameters:

where (Q | None) – Q object for WHERE clause conditions

fetch(*fields)[source]

Add FETCH clause to resolve references.

Parameters:

*fields (str) – Field names to fetch

Returns:

Self for method chaining

Return type:

QueryExpression

group_by(*fields)[source]

Add GROUP BY clause.

Parameters:

*fields (str) – Field names to group by

Returns:

Self for method chaining

Return type:

QueryExpression

order_by(field, direction='ASC')[source]

Add ORDER BY clause.

Parameters:
  • field (str) – Field name to order by

  • direction (str) – ‘ASC’ or ‘DESC’

Returns:

Self for method chaining

Return type:

QueryExpression

limit(value)[source]

Add LIMIT clause.

Parameters:

value (int) – Maximum number of results

Returns:

Self for method chaining

Return type:

QueryExpression

start(value)[source]

Add START clause for pagination.

Parameters:

value (int) – Number of results to skip

Returns:

Self for method chaining

Return type:

QueryExpression

apply_to_queryset(queryset)[source]

Apply this expression to a queryset.

Parameters:

queryset – BaseQuerySet to apply expression to

Returns:

Modified queryset

Pagination

class surrealengine.pagination.PaginationResult(items, page, per_page, total)[source]

Bases: Generic[T]

Container for paginated query results with metadata.

This class provides a container for paginated query results along with metadata about the pagination, such as the total number of items, the number of pages, and whether there are next or previous pages.

items

The items in the current page

page

The current page number

per_page

The number of items per page

total

The total number of items across all pages

pages

The total number of pages

has_next

Whether there is a next page

has_prev

Whether there is a previous page

__init__(items, page, per_page, total)[source]

Initialize a PaginationResult.

Parameters:
  • items (List[T]) – The items in the current page

  • page (int) – The current page number

  • per_page (int) – The number of items per page

  • total (int) – The total number of items across all pages

__iter__()[source]

Iterate over the items in the current page.

__len__()[source]

Get the number of items in the current page.

__getitem__(index)[source]

Get an item from the current page by index.

__repr__()[source]

Get a string representation of the pagination result.

Usage Examples

Basic Queries

from surrealengine import Document, StringField, IntField

class User(Document):
    name = StringField(required=True)
    age = IntField()

# Get all users
users = await User.objects.all()

# Filter users
adults = await User.objects.filter(age__gte=18).all()

# Get a single user
user = await User.objects.get(name="Alice")

Advanced Filtering

from surrealengine import Q

# Complex queries with Q objects
query = Q(age__gte=18) & (Q(name__startswith="A") | Q(name__startswith="B"))
users = await User.objects.filter(query).all()

# Ordering and limiting
recent_users = await User.objects.order_by("-created_at").limit(10).all()

# Counting
user_count = await User.objects.filter(age__gte=18).count()

Aggregation

# Count by group
age_counts = await User.objects.group_by("age").count()

# Average age
avg_age = await User.objects.aggregate(avg_age=Avg("age"))

Relationship Queries

class Post(Document):
    title = StringField(required=True)
    author = ReferenceField(User)

# Query with joins
posts_with_authors = await Post.objects.select_related("author").all()

# Reverse relationships
user_posts = await user.fetch_relation("posts", Post)

Pagination

# Paginated results
page = await User.objects.paginate(page=1, per_page=20)
users = page.items
total_count = page.total

# Cursor-based pagination
cursor_page = await User.objects.cursor_paginate(
    cursor="eyJ1c2VyX2lkIjoxMjN9",
    limit=20
)