Document API Reference

This module provides the foundation for defining and working with documents in SurrealDB using an Object-Document Mapper (ODM) pattern.

Document Classes

class surrealengine.document.Document(**values)[source]

Bases: object

Base class for all documents.

This class provides the foundation for all document models in the ORM. It includes methods for CRUD operations, validation, and serialization.

objects

QuerySetDescriptor for querying documents of this class

_data

Dictionary of field values

_changed_fields

List of field names that have been changed

_fields

Dictionary of fields for this document class (class attribute)

_fields_ordered

List of field names in order of definition (class attribute)

_meta

Dictionary of metadata for this document class (class attribute)

Meta Options:

The Meta inner class can be used to configure various document options:

  • collection (str): Name of the database collection/table. Defaults to lowercase class name.

  • indexes (List[Dict]): List of index definitions. Each index dict can contain: - keys (List[str]): Field names to include in the index - unique (bool): Whether the index enforces uniqueness (default: False) - name (str): Custom name for the index - type (str): Index type (e.g., “search” for full-text search)

  • id_field (str): Name of the ID field. Defaults to “id”.

  • strict (bool): Whether to enforce strict field validation. Defaults to True. When False, allows dynamic fields not defined in the schema.

  • time_series (bool): Whether this is a time series table. Defaults to False.

  • time_field (str): Field to use for time series timestamp. Required when time_series is True.

  • abstract (bool): Whether this document is abstract. Abstract documents are not registered with the database and are meant to be inherited.

Example:

class User(Document):
    name = StringField(required=True)
    email = StringField(indexed=True, unique=True)

    class Meta:
        collection = "users"
        indexes = [
            {"fields": ["email"], "unique": True},
            {"fields": ["name", "created_at"]}
        ]
__init__(**values)[source]

Initialize a new Document.

Parameters:

**values (Any) – Field values to set on the document

Raises:

AttributeError – If strict mode is enabled and an unknown field is provided

__getattr__(name)[source]

Get a field value.

This method is called when an attribute is not found through normal lookup. It checks if the attribute is a field and returns its value if it is.

Parameters:

name (str) – Name of the attribute to get

Returns:

The field value

Raises:

AttributeError – If the attribute is not a field

Return type:

Any

__setattr__(name, value)[source]

Set a field value.

This method is called when an attribute is set. It checks if the attribute is a field and validates the value if it is.

Parameters:
  • name (str) – Name of the attribute to set

  • value (Any) – Value to set

property id: Any

Get the document ID.

Returns:

The document ID

has_changed(field=None)[source]

Check if the document or a specific field has changed.

Parameters:

field (str) – Optional field name to check. If None, checks if any field changed.

Returns:

True if the document/field has changed, False otherwise

Return type:

bool

Examples

>>> user = User(name="John", age=30)
>>> await user.save()
>>> user.age = 31
>>> user.has_changed()  # True
>>> user.has_changed('age')  # True
>>> user.has_changed('name')  # False
get_changes()[source]

Get a dictionary of all changed fields and their new values.

Returns:

Dictionary mapping field names to their new values

Return type:

Dict[str, Any]

Examples

>>> user.age = 31
>>> user.name = "Jane"
>>> user.get_changes()  # {'age': 31, 'name': 'Jane'}
get_original_value(field)[source]

Get the original value of a field before any changes.

Parameters:

field (str) – Name of the field

Returns:

The original value of the field

Return type:

Any

Examples

>>> user.age = 31  # was 30
>>> user.get_original_value('age')  # 30
revert_changes(fields=None)[source]

Revert changes to original values.

Parameters:

fields (List[str]) – Optional list of field names to revert. If None, reverts all changes.

Examples

>>> user.age = 31
>>> user.name = "Jane"
>>> user.revert_changes(['age'])  # Only revert age
>>> user.revert_changes()  # Revert all changes
property is_dirty: bool

Check if the document has unsaved changes.

Returns:

True if there are unsaved changes, False otherwise

Examples

>>> user.is_dirty  # False
>>> user.age = 31
>>> user.is_dirty  # True
>>> await user.save()
>>> user.is_dirty  # False
property is_clean: bool

Check if the document has no unsaved changes.

Returns:

True if there are no unsaved changes, False otherwise

property dirty_fields: List[str]

Get list of field names that have been changed.

Returns:

List of field names with unsaved changes

Examples

>>> user.age = 31
>>> user.name = "Jane"
>>> user.dirty_fields  # ['age', 'name']
mark_clean()[source]

Mark the document as clean (no pending changes).

This updates the original data to match current data and clears changed fields. Usually called automatically after successful save operations.

get_changed_data_for_update()[source]

Get only the changed fields formatted for database update.

Returns:

Dictionary of changed fields in database format

Return type:

Dict[str, Any]

This is used internally for optimized updates that only send changed fields.

validate()[source]

Validate all fields.

This method validates all fields in the document against their validation rules.

Raises:

ValidationError – If a field fails validation

to_dict()[source]

Convert the document to a dictionary.

This method converts the document to a dictionary containing all field values including the document ID. It ensures that RecordID objects are properly converted to strings for JSON serialization. It also recursively converts embedded documents to dictionaries.

Returns:

Dictionary of field values including ID

Return type:

Dict[str, Any]

to_db()[source]

Convert the document to a database-friendly dictionary.

This method converts the document to a dictionary suitable for storage in the database. It applies field-specific conversions and includes only non-None values unless the field is required.

Returns:

Dictionary of field values for the database

Return type:

Dict[str, Any]

classmethod from_db(data, dereference=False, partial=False)[source]

Create a document instance from database data.

Parameters:
  • data (Any) – Data from the database (dictionary, string, RecordID, etc.)

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

  • partial (bool) – Whether the data is a partial document (default: False)

Returns:

A new document instance

Return type:

Document

async resolve_references(depth=1)[source]

Resolve all references in this document using FETCH.

This method uses SurrealDB’s FETCH clause to efficiently resolve references instead of making individual queries for each reference.

Parameters:

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

Returns:

The document instance with resolved references

Return type:

Document

resolve_references_sync(depth=1)[source]

Resolve all references in this document synchronously using FETCH.

This method uses SurrealDB’s FETCH clause to efficiently resolve references instead of making individual queries for each reference.

Parameters:

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

Returns:

The document instance with resolved references

Return type:

Document

async classmethod get(id, dereference=False, dereference_depth=1, **kwargs)[source]

Get a document by ID with optional dereferencing using FETCH.

This method retrieves a document by ID and optionally resolves references using SurrealDB’s FETCH clause for efficient reference resolution.

Parameters:
  • id (Any) – The ID of the document to retrieve

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

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

  • **kwargs (Any) – Additional arguments to pass to the get method

Returns:

The document instance with optionally resolved references

Return type:

Document

Examples

Get a document by ID:

>>> user = await User.get("user:123")
>>> print(f"Retrieved user: {user.name}")

Get with full record ID:

>>> task = await Task.get("tasks:abc123")
>>> print(f"Task: {task.title}")

Get with reference dereferencing:

>>> post = await Post.get("post:456", dereference=True)
>>> print(f"Post by: {post.author.name}")  # author is resolved

Get with deep dereferencing:

>>> post = await Post.get("post:456", dereference=True, dereference_depth=2)
# Resolves references 2 levels deep
classmethod get_sync(id, dereference=False, dereference_depth=1, **kwargs)[source]

Get a document by ID with optional dereferencing synchronously using FETCH.

This method retrieves a document by ID and optionally resolves references using SurrealDB’s FETCH clause for efficient reference resolution.

Parameters:
  • id (Any) – The ID of the document to retrieve

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

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

  • **kwargs (Any) – Additional arguments to pass to the get method

Returns:

The document instance with optionally resolved references

Return type:

Document

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

Update the document with new data.

Parameters:
  • connection (Any | None) – The database connection to use (optional)

  • **kwargs – Fields to update

Returns:

The updated document instance

Return type:

Document

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

Update the document with new data synchronously.

Parameters:
  • connection (Any | None) – The database connection to use (optional)

  • **kwargs – Fields to update

Returns:

The updated document instance

Return type:

Document

async save(connection=None)[source]

Save the document to the database asynchronously.

This method saves the document to the database, either creating a new document or updating an existing one.

save_sync(connection=None)[source]

Save the document to the database synchronously.

This method saves the document to the database, either creating a new document or updating an existing one based on whether the document has an ID.

Parameters:

connection (Any | None) – The database connection to use (optional)

Returns:

The saved document instance

Raises:

ValidationError – If the document fails validation

Return type:

Document

async delete(connection=None)[source]

Delete the document from the database asynchronously.

This method deletes the document from the database.

Parameters:

connection (Any | None) – The database connection to use (optional)

Returns:

True if the document was deleted

Raises:

ValueError – If the document doesn’t have an ID

Return type:

bool

Examples

Delete a document:

>>> user = await User.get("user:123")
>>> await user.delete()
>>> print("User deleted successfully")

Delete with custom connection:

>>> await user.delete(connection=custom_connection)

Bulk delete pattern:

>>> for task in await Task.objects.filter(completed=True).all():
...     await task.delete()
delete_sync(connection=None)[source]

Delete the document from the database synchronously.

This method deletes the document from the database.

Parameters:

connection (Any | None) – The database connection to use (optional)

Returns:

True if the document was deleted

Raises:

ValueError – If the document doesn’t have an ID

Return type:

bool

async refresh(connection=None)[source]

Refresh the document from the database asynchronously.

This method refreshes the document’s data from the database.

Parameters:

connection (Any | None) – The database connection to use (optional)

Returns:

The refreshed document instance

Raises:

ValueError – If the document doesn’t have an ID

Return type:

Document

refresh_sync(connection=None)[source]

Refresh the document from the database synchronously.

This method refreshes the document’s data from the database.

Parameters:

connection (Any | None) – The database connection to use (optional)

Returns:

The refreshed document instance

Raises:

ValueError – If the document doesn’t have an ID

Return type:

Document

classmethod relates(relation_name)[source]

Get a RelationQuerySet for a specific relation.

This method returns a function that creates a RelationQuerySet for the specified relation name. The function can be called with an optional connection parameter.

Parameters:

relation_name (str) – Name of the relation

Returns:

Function that creates a RelationQuerySet

Return type:

callable

async fetch_relation(relation_name, target_document=None, relation_document=None, connection=None, **filters)[source]

Fetch related documents asynchronously.

This method fetches documents related to this document through the specified relation.

Parameters:
  • relation_name (str) – Name of the relation

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

  • relation_document (Type | None) – The document class representing the relation (optional)

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

List of related documents, relation documents, or relation records

Return type:

List[Any]

fetch_relation_sync(relation_name, target_document=None, relation_document=None, connection=None, **filters)[source]

Fetch related documents synchronously.

This method fetches documents related to this document through the specified relation.

Parameters:
  • relation_name (str) – Name of the relation

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

  • relation_document (Type | None) – The document class representing the relation (optional)

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

List of related documents, relation documents, or relation records

Return type:

List[Any]

async resolve_relation(relation_name, target_document_class=None, relation_document=None, connection=None)[source]

Resolve related documents from a relation fetch result asynchronously.

This method resolves related documents from a relation fetch result. It fetches the relation data and then resolves each related document.

Parameters:
  • relation_name (str) – Name of the relation to resolve

  • target_document_class (Type | None) – Class of the target document (optional)

  • relation_document (Type | None) – The document class representing the relation (optional)

  • connection (Any | None) – Database connection to use (optional)

Returns:

List of resolved document instances

Return type:

List[Any]

resolve_relation_sync(relation_name, target_document_class=None, relation_document=None, connection=None)[source]

Resolve related documents from a relation fetch result synchronously.

This method resolves related documents from a relation fetch result. It fetches the relation data and then resolves each related document.

Parameters:
  • relation_name (str) – Name of the relation to resolve

  • target_document_class (Type | None) – Class of the target document (optional)

  • relation_document (Type | None) – The document class representing the relation (optional)

  • connection (Any | None) – Database connection to use (optional)

Returns:

List of resolved document instances

Return type:

List[Any]

async relate_to(relation_name, target_instance, connection=None, **attrs)[source]

Create a relation to another document asynchronously.

This method creates a relation from this document to another document.

Parameters:
  • relation_name (str) – Name of the relation

  • target_instance (Any) – The document instance to relate to

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The created relation record or None if creation failed

Return type:

Any | None

Examples

Create a simple relation:

>>> person = await Person.get("person:john")
>>> book = await Book.get("book:novel")
>>> relation = await person.relate_to("authored", book)

Create relation with attributes:

>>> await person.relate_to("authored", book,
...     date_written="2022-01-15T00:00:00Z",
...     is_primary_author=True)

Create multiple relations:

>>> for book in user_books:
...     await author.relate_to("wrote", book, year=2023)
relate_to_sync(relation_name, target_instance, connection=None, **attrs)[source]

Create a relation to another document synchronously.

This method creates a relation from this document to another document.

Parameters:
  • relation_name (str) – Name of the relation

  • target_instance (Any) – The document instance to relate to

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The created relation record or None if creation failed

Return type:

Any | None

async update_relation_to(relation_name, target_instance, connection=None, **attrs)[source]

Update a relation to another document asynchronously.

This method updates a relation from this document to another document.

Parameters:
  • relation_name (str) – Name of the relation

  • target_instance (Any) – The document instance the relation is to

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The updated relation record or None if update failed

Return type:

Any | None

update_relation_to_sync(relation_name, target_instance, connection=None, **attrs)[source]

Update a relation to another document synchronously.

This method updates a relation from this document to another document.

Parameters:
  • relation_name (str) – Name of the relation

  • target_instance (Any) – The document instance the relation is to

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The updated relation record or None if update failed

Return type:

Any | None

async delete_relation_to(relation_name, target_instance=None, connection=None)[source]

Delete a relation to another document asynchronously.

This method deletes a relation from this document to another document. If target_instance is not provided, it deletes all relations with the specified name from this document.

Parameters:
  • relation_name (str) – Name of the relation

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

  • connection (Any | None) – The database connection to use (optional)

Returns:

Number of deleted relations

Return type:

int

delete_relation_to_sync(relation_name, target_instance=None, connection=None)[source]

Delete a relation to another document synchronously.

This method deletes a relation from this document to another document. If target_instance is not provided, it deletes all relations with the specified name from this document.

Parameters:
  • relation_name (str) – Name of the relation

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

  • connection (Any | None) – The database connection to use (optional)

Returns:

Number of deleted relations

Return type:

int

async traverse_path(path_spec, target_document=None, connection=None, **filters)[source]

Traverse a path in the graph asynchronously.

This method traverses a path in the graph starting from this document. The path_spec is a string like “->[watched]->->[acted_in]->” which describes a path through the graph.

Parameters:
  • path_spec (str) – String describing the path to traverse

  • target_document (Type | None) – The document class to return instances of (optional)

  • connection (Any | None) – The database connection to use (optional)

  • **filters (Any) – Filters to apply to the results

Returns:

List of documents or path results

Raises:

ValueError – If the document is not saved

Return type:

List[Any]

traverse_path_sync(path_spec, target_document=None, connection=None, **filters)[source]

Traverse a path in the graph synchronously.

This method traverses a path in the graph starting from this document. The path_spec is a string like “->[watched]->->[acted_in]->” which describes a path through the graph.

Parameters:
  • path_spec (str) – String describing the path to traverse

  • target_document (Type | None) – The document class to return instances of (optional)

  • connection (Any | None) – The database connection to use (optional)

  • **filters (Any) – Filters to apply to the results

Returns:

List of documents or path results

Raises:

ValueError – If the document is not saved

Return type:

List[Any]

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

Create multiple documents in batches.

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

  • batch_size (int) – Number of documents per batch

  • validate (bool) – Whether to validate documents before creation

  • return_documents (bool) – Whether to return created documents

Returns:

List of created documents if return_documents=True, else count of created documents

Return type:

List[Any] | int

classmethod bulk_create_sync(documents, batch_size=1000, validate=True, return_documents=True, connection=None)[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)

  • connection (Any | None) – The database connection to use (optional)

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 classmethod create_index(index_name, fields, unique=False, search=False, analyzer=None, comment=None, connection=None)[source]

Create an index on the document’s collection asynchronously.

Parameters:
  • index_name (str) – Name of the index

  • fields (List[str]) – List of field names to include in the index

  • unique (bool) – Whether the index should enforce uniqueness

  • search (bool) – Whether the index is a search index

  • analyzer (str | None) – Analyzer to use for search indexes

  • comment (str | None) – Optional comment for the index

  • connection (Any | None) – Optional connection to use

classmethod create_index_sync(index_name, fields, unique=False, search=False, analyzer=None, comment=None, connection=None)[source]

Create an index on the document’s collection synchronously.

Parameters:
  • index_name (str) – Name of the index

  • fields (List[str]) – List of field names to include in the index

  • unique (bool) – Whether the index should enforce uniqueness

  • search (bool) – Whether the index is a search index

  • analyzer (str | None) – Analyzer to use for search indexes

  • comment (str | None) – Optional comment for the index

  • connection (Any | None) – Optional connection to use

async classmethod create_indexes(connection=None)[source]

Create all indexes defined for this document class asynchronously.

This method creates indexes defined in the Meta class and also creates indexes for fields marked as indexed.

Parameters:

connection (Any | None) – Optional connection to use

classmethod create_indexes_sync(connection=None)[source]

Create all indexes defined for this document class synchronously.

This method creates indexes defined in the Meta class and also creates indexes for fields marked as indexed.

Parameters:

connection (Any | None) – Optional connection to use

async classmethod create_table(connection=None, schemafull=True)[source]

Create the table for this document class asynchronously.

Parameters:
  • connection (Any | None) – Optional connection to use

  • schemafull (bool) – Whether to create a SCHEMAFULL table (default: True)

Examples

Create a SCHEMAFULL table:

>>> await User.create_table()
>>> print("Created users table with strict schema")

Create a SCHEMALESS table:

>>> await FlexibleDoc.create_table(schemafull=False)
>>> print("Created flexible table without schema constraints")

Create with custom connection:

>>> await Person.create_table(connection=custom_connection)

Create multiple tables:

>>> await Person.create_table()
>>> await Address.create_table()
>>> await Organization.create_table()
classmethod create_table_sync(connection=None, schemafull=True)[source]

Create the table for this document class synchronously.

classmethod to_dataclass()[source]

Convert the document class to a dataclass.

This method creates a dataclass based on the document’s fields. It uses the field names, types, and whether they are required. Required fields have no default value, making them required during initialization. Non-required fields use None as default if they don’t define one. A __post_init__ method is added to validate all fields after initialization.

Returns:

A dataclass type based on the document’s fields

classmethod create_materialized_view(name, query, refresh_interval=None, aggregations=None, select_fields=None, **kwargs)[source]

Create a materialized view based on a query.

This method creates a materialized view in SurrealDB based on a query. Materialized views are precomputed views of data that can be used to improve query performance for frequently accessed aggregated data.

Parameters:
  • name (str) – The name of the materialized view

  • query (QuerySet) – The query that defines the materialized view

  • refresh_interval (str) – The interval at which the view is refreshed (e.g., “1h”, “30m”)

  • aggregations – Dictionary of field names and aggregation functions

  • select_fields – List of fields to select (if None, selects all fields)

  • **kwargs – Additional keyword arguments to pass to the MaterializedView constructor

Returns:

A MaterializedView instance

Document.objects

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

surrealengine.document.connection

The database connection to use for queries

class surrealengine.document.RelationDocument(**values)[source]

Bases: Document

A Document that represents a relationship between two documents.

RelationDocuments should be used to model relationships with additional attributes. They can be used with Document.relates(), Document.fetch_relation(), and Document.resolve_relation().

class Meta[source]

Bases: object

Meta options for RelationDocument.

abstract = True
classmethod get_relation_name()[source]

Get the name of the relation.

By default, this is the lowercase name of the class. Override this method to customize the relation name.

Returns:

The name of the relation

Return type:

str

classmethod relates(from_document=None, to_document=None)[source]

Get a RelationQuerySet for this relation.

This method returns a function that creates a RelationQuerySet for this relation. The function can be called with an optional connection parameter.

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

  • to_document (Type | None) – The document class the relation is to (optional)

Returns:

Function that creates a RelationQuerySet

Return type:

callable

async classmethod create_relation(from_instance, to_instance, **attrs)[source]

Create a relation between two instances asynchronously.

This method creates a relation between two document instances and returns a RelationDocument instance representing the relationship.

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:

A RelationDocument instance representing the relationship

Raises:

ValueError – If either instance is not saved

Return type:

RelationDocument

classmethod create_relation_sync(from_instance, to_instance, **attrs)[source]

Create a relation between two instances synchronously.

This method creates a relation between two document instances and returns a RelationDocument instance representing the relationship.

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:

A RelationDocument instance representing the relationship

Raises:

ValueError – If either instance is not saved

Return type:

RelationDocument

classmethod find_by_in_document(in_doc, **additional_filters)[source]

Query RelationDocument by in_document field.

Parameters:
  • in_doc – The document instance or ID to filter by

  • **additional_filters – Additional filters to apply

Returns:

QuerySet filtered by in_document

classmethod find_by_in_document_sync(in_doc, **additional_filters)[source]

Query RelationDocument by in_document field synchronously.

Parameters:
  • in_doc – The document instance or ID to filter by

  • **additional_filters – Additional filters to apply

Returns:

QuerySet filtered by in_document

classmethod find_by_in_documents(in_docs, **additional_filters)[source]

Query RelationDocument where the in reference is any of the provided records (async-ready queryset).

Parameters:
  • in_docs – Iterable of items; each item may be a Document instance, RecordID, ‘table:id’ string, or dict with ‘id’.

  • **additional_filters – Any additional filters to apply to the query.

Returns:

QuerySet filtered by in__in

classmethod find_by_in_documents_sync(in_docs, **additional_filters)[source]

Synchronous version of find_by_in_documents.

Parameters:
  • in_docs – Iterable of items; each item may be a Document instance, RecordID, ‘table:id’ string, or dict with ‘id’.

  • **additional_filters – Any additional filters to apply to the query.

Returns:

QuerySet filtered by in__in

async resolve_out(connection=None)[source]

Resolve the out_document field asynchronously.

This method resolves the out_document field if it’s currently just an ID reference. If the out_document is already a document instance, it returns it directly.

Parameters:

connection – Database connection to use (optional)

Returns:

The resolved out_document instance

async update(connection=None, **attrs)

Update the relation document without deleting existing data.

This method updates only the specified attributes of the relation document without affecting other attributes, unlike the save() method which uses upsert.

Parameters:
  • relation_doc (RelationDocument) – The RelationDocument instance to update

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The updated relation document

Raises:

ValueError – If the document is not saved

Return type:

RelationDocument

update_sync(connection=None, **attrs)

Update the relation document without deleting existing data synchronously.

This method updates only the specified attributes of the relation document without affecting other attributes, unlike the save() method which uses upsert.

Parameters:
  • relation_doc (RelationDocument) – The RelationDocument instance to update

  • connection (Any | None) – The database connection to use (optional)

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

Returns:

The updated relation document

Raises:

ValueError – If the document is not saved

Return type:

RelationDocument

resolve_out_sync(connection=None)[source]

Resolve the out_document field synchronously.

This method resolves the out_document field if it’s currently just an ID reference. If the out_document is already a document instance, it returns it directly.

Parameters:

connection – Database connection to use (optional)

Returns:

The resolved out_document instance

Graph and Relations

class surrealengine.graph.GraphQuery(connection)[source]

Bases: object

Helper for complex graph queries.

This class provides a fluent interface for building and executing complex graph traversal queries in SurrealDB. It allows defining a starting point, traversal path, end point, and filters for the query.

connection

The database connection to use for queries

query_parts

List of query parts

start_class

The document class to start the traversal from

start_filters

Filters to apply to the starting documents

path_spec

The traversal path specification

end_class

The document class to end the traversal at

end_filters

Filters to apply to the end results

__init__(connection)[source]

Initialize a new GraphQuery.

Parameters:

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

start_from(document_class, **filters)[source]

Set the starting point for the graph query.

Parameters:
  • document_class (Type) – The document class to start the traversal from

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

Returns:

The GraphQuery instance for method chaining

Return type:

GraphQuery

traverse(path_spec)[source]

Define a traversal path.

Parameters:

path_spec (str) – The traversal path specification, e.g., “->[relation]->”

Returns:

The GraphQuery instance for method chaining

Return type:

GraphQuery

end_at(document_class=None)[source]

Set the end point document type.

Parameters:

document_class (Type | None) – The document class to end the traversal at

Returns:

The GraphQuery instance for method chaining

Return type:

GraphQuery

filter_results(**filters)[source]

Add filters to the end results.

Parameters:

**filters (Any) – Filters to apply to the end results

Returns:

The GraphQuery instance for method chaining

Return type:

GraphQuery

async execute()[source]

Execute the graph query.

This method builds and executes the graph query based on the components defined using the fluent interface methods. It validates that the required components are present, builds the query string, executes it, and processes the results.

Returns:

List of results, either document instances or raw results

Raises:

ValueError – If required components are missing

Return type:

List[Any]

Schemaless Support

class surrealengine.schemaless.SchemalessQuerySet(table_name, connection)[source]

Bases: BaseQuerySet

QuerySet for schemaless operations.

This class provides a query builder for tables without a predefined schema. It extends BaseQuerySet to provide methods for querying and manipulating documents in a schemaless manner.

table_name

The name of the table to query

connection

The database connection to use for queries

__init__(table_name, connection)[source]

Initialize a new SchemalessQuerySet.

Parameters:
  • table_name (str) – The name of the table to query

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

async all()[source]

Execute the query and return all results asynchronously.

This method builds and executes the query, then processes the results based on whether a matching document class is found. If a matching document class is found, the results are converted to instances of that class. Otherwise, they are converted to SimpleNamespace objects.

Returns:

List of results, either document instances or SimpleNamespace objects

Return type:

List[Any]

all_sync()[source]

Execute the query and return all results synchronously.

This method builds and executes the query, then processes the results based on whether a matching document class is found. If a matching document class is found, the results are converted to instances of that class. Otherwise, they are converted to SimpleNamespace objects.

Returns:

List of results, either document instances or SimpleNamespace objects

Return type:

List[Any]

async get(**kwargs)[source]

Get a single document matching the query asynchronously.

This method provides special handling for ID-based lookups, using the direct select method with RecordID. For non-ID lookups, it falls back to the base class implementation.

Parameters:

**kwargs (Any) – 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 provides special handling for ID-based lookups, using the direct select method with RecordID. For non-ID lookups, it falls back to the base class implementation.

Parameters:

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

Returns:

The matching document

Raises:
Return type:

Any

async bulk_create(documents, batch_size=1000, 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 return the created documents.

Parameters:
  • documents (List[Dict[str, Any]]) – List of dictionaries representing documents to create

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

  • 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, 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 return the created documents.

Parameters:
  • documents (List[Dict[str, Any]]) – List of dictionaries representing documents to create

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

  • 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

class surrealengine.schemaless.SchemalessTable(name, connection)[source]

Bases: object

Dynamic table accessor.

This class provides access to a specific table in the database without requiring a predefined schema. It allows querying the table using the objects property or by calling the instance directly with filters.

name

The name of the table

connection

The database connection to use for queries

__init__(name, connection)[source]

Initialize a new SchemalessTable.

Parameters:
  • name (str) – The name of the table

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

async relate(from_id, relation, to_id, **attrs)[source]

Create a relation between two records asynchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record to create the relation from

  • relation (str) – The name of the relation

  • to_id (str | RecordID) – The ID of the record to create the relation to

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

Returns:

The created relation record or None if creation failed

Return type:

Any | None

relate_sync(from_id, relation, to_id, **attrs)[source]

Create a relation between two records synchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record to create the relation from

  • relation (str) – The name of the relation

  • to_id (str | RecordID) – The ID of the record to create the relation to

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

Returns:

The created relation record or None if creation failed

Return type:

Any | None

Get related records asynchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record to get related records for

  • relation (str) – The name of the relation

  • target_table (str | None) – The name of the target table (optional)

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

Returns:

List of related records or relation records

Return type:

List[Any]

Get related records synchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record to get related records for

  • relation (str) – The name of the relation

  • target_table (str | None) – The name of the target table (optional)

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

Returns:

List of related records or relation records

Return type:

List[Any]

async update_relation(from_id, relation, to_id, **attrs)[source]

Update an existing relation asynchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record the relation is from

  • relation (str) – The name of the relation

  • to_id (str | RecordID) – The ID of the record the relation is to

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

Returns:

The updated relation record or None if update failed

Return type:

Any | None

update_relation_sync(from_id, relation, to_id, **attrs)[source]

Update an existing relation synchronously.

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

Parameters:
  • from_id (str | RecordID) – The ID of the record the relation is from

  • relation (str) – The name of the relation

  • to_id (str | RecordID) – The ID of the record the relation is to

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

Returns:

The updated relation record or None if update failed

Return type:

Any | None

async delete_relation(from_id, relation, to_id=None)[source]

Delete a relation asynchronously.

This method deletes a relation between two records in the database. If to_id is not provided, it deletes all relations from from_id.

Parameters:
  • from_id (str | RecordID) – The ID of the record the relation is from

  • relation (str) – The name of the relation

  • to_id (str | RecordID | None) – The ID of the record the relation is to (optional)

Returns:

Number of deleted relations

Return type:

int

delete_relation_sync(from_id, relation, to_id=None)[source]

Delete a relation synchronously.

This method deletes a relation between two records in the database. If to_id is not provided, it deletes all relations from from_id.

Parameters:
  • from_id (str | RecordID) – The ID of the record the relation is from

  • relation (str) – The name of the relation

  • to_id (str | RecordID | None) – The ID of the record the relation is to (optional)

Returns:

Number of deleted relations

Return type:

int

async create_index(index_name, fields, unique=False, search=False, analyzer=None, comment=None)[source]

Create an index on this table asynchronously.

Parameters:
  • index_name (str) – Name of the index

  • fields (List[str]) – List of field names to include in the index

  • unique (bool) – Whether the index should enforce uniqueness

  • search (bool) – Whether the index is a search index

  • analyzer (str | None) – Analyzer to use for search indexes

  • comment (str | None) – Optional comment for the index

create_index_sync(index_name, fields, unique=False, search=False, analyzer=None, comment=None)[source]

Create an index on this table synchronously.

Parameters:
  • index_name (str) – Name of the index

  • fields (List[str]) – List of field names to include in the index

  • unique (bool) – Whether the index should enforce uniqueness

  • search (bool) – Whether the index is a search index

  • analyzer (str | None) – Analyzer to use for search indexes

  • comment (str | None) – Optional comment for the index

property objects: SchemalessQuerySet

Get a query set for this table.

Returns:

A SchemalessQuerySet for querying this table

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

Query the table with filters asynchronously.

This method allows calling the table instance directly with filters to query the table. It supports pagination through limit and start parameters or the page parameter. It returns the results as SimpleNamespace objects if they aren’t already Document instances.

Parameters:
  • 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 results, either document instances or SimpleNamespace objects

Return type:

List[Any]

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

Query the table with filters synchronously.

This method allows calling the table synchronously with filters to query the table. It supports pagination through limit and start parameters or the page parameter. It returns the results as SimpleNamespace objects if they aren’t already Document instances.

Parameters:
  • 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 results, either document instances or SimpleNamespace objects

Return type:

List[Any]

async transaction(coroutines)[source]

Execute multiple operations in a transaction asynchronously.

This method executes a list of coroutines within a transaction, committing the transaction if all operations succeed or canceling it if any operation fails.

Parameters:

coroutines (List[Callable]) – List of coroutines to execute in the transaction

Returns:

List of results from the coroutines

Raises:

Exception – If any operation in the transaction fails

Return type:

List[Any]

transaction_sync(callables)[source]

Execute multiple operations in a transaction synchronously.

This method executes a list of callables within a transaction, committing the transaction if all operations succeed or canceling it if any operation fails.

Parameters:

callables (List[Callable]) – List of callables to execute in the transaction

Returns:

List of results from the callables

Raises:

Exception – If any operation in the transaction fails

Return type:

List[Any]

async bulk_create(documents, batch_size=1000, 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 return the created documents.

Parameters:
  • documents (List[Dict[str, Any]]) – List of dictionaries representing documents to create

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

  • 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, 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 return the created documents.

Parameters:
  • documents (List[Dict[str, Any]]) – List of dictionaries representing documents to create

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

  • 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

class surrealengine.schemaless.SurrealEngine(connection)[source]

Bases: object

Dynamic database accessor.

This class provides dynamic access to tables in the database without requiring predefined schemas. It allows accessing tables as attributes of the instance.

connection

The database connection to use for queries

is_async

Whether the connection is asynchronous

__init__(connection)[source]

Initialize a new SurrealEngine.

Parameters:

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

__getattr__(name)[source]

Get a table accessor for the given table name.

This method allows accessing tables as attributes of the instance.

Parameters:

name (str) – The name of the table

Returns:

A SchemalessTable for accessing the table

Return type:

SchemalessTable

Metaclasses

class surrealengine.document.DocumentMetaclass(name, bases, attrs)[source]

Bases: type

Metaclass for Document classes.

This metaclass processes field attributes in Document classes to create a structured schema. It handles field inheritance, field naming, and metadata configuration.

_meta

Dictionary of metadata for the document class

_fields

Dictionary of fields for the document class

_fields_ordered

List of field names in order of definition

static __new__(mcs, name, bases, attrs)[source]

Create a new Document class.

This method processes the class attributes to create a structured schema. It handles field inheritance, field naming, and metadata configuration.

Parameters:
  • name (str) – Name of the class being created

  • bases (tuple) – Tuple of base classes

  • attrs (Dict[str, Any]) – Dictionary of class attributes

Returns:

The new Document class

Return type:

Type

Usage Examples

Basic Document Definition

from surrealengine import Document, StringField, IntField

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

    class Meta:
        collection = "users"

Document Operations

# Create and save a document
user = User(name="Alice", age=30)
await user.save()

# Query documents
users = await User.objects.filter(age__gte=18).all()

# Update a document
user.age = 31
await user.save()

# Delete a document
await user.delete()

Relationships

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

# Create relationship
book = Book(title="Python Guide", author=user)
await book.save()

# Fetch with references resolved
book_with_author = await Book.get(book.id, dereference=True)
print(book_with_author.author.name)  # "Alice"