Changelog¶
SurrealEngine Changelog¶
All notable changes to the SurrealEngine project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]¶
[0.5.1] - 2025-12-30¶
Fixed¶
Documentation Consistency: Unified the documentation structure to ensure consistent navigation menus across User Guide and API Reference sections.
API Reference Consolidation: Cleaned up redundant auto-generated API pages and merged orphaned modules (
graph,schemaless,base_query,pagination, etc.) into curated reference pages.Docstring Formatting: Corrected numerous docstring errors and converted Markdown-style code blocks to ReStructuredText (RST) to fix Sphinx build warnings.
Core Import Fix: Fixed a missing
ValidationErrorimport indocument.pythat was causing documentation build failures.Field Documentation: Fixed incorrect module paths in
api/fields.rstensuring all field classes are correctly documented viaautodoc.
[0.5.0] - 2025-12-30¶
Added¶
QuerySet Enhancements:
omit(*fields): Exclude specific fields from the results.timeout(duration): Set a timeout for the query execution (e.g., “5s”).tempfiles(value): Enable or disable using temporary files for large queries.with_explain(full=False): Builder method to explain the query execution plan.explain()andexplain_sync()now also supportfull=Trueargument.no_index(): UseWITH NOINDEXclause to bypass indexes.group_by(all=True): Support forGROUP ALLclause.
Advanced Filter Operators: Added support for SurrealDB set operators including:
contains_any,contains_all,contains_noneinside,not_insideall_inside,any_inside,none_inside
Live Query Ergonomics:
LiveEventclass: Typed event objects yieldingaction(CREATE/UPDATE/DELETE),data,ts, andid.actionfiltering:QuerySet.live(action="CREATE")oraction=["CREATE", "UPDATE"]to filter events client-side.
Materialized Views:
create(overwrite=True)/create(if_not_exists=True): Support forOVERWRITEandIF NOT EXISTSclauses inDEFINE TABLE.Improved
GROUP BYparsing to robustly handleQuerySetgrouping configuration.
Changed¶
Deprecation:
MaterializedView.refresh()andrefresh_sync()are now deprecated as SurrealDB views are live and do not require manual refreshing.Explain Method:
QuerySet.explain()now supportsfull=Trueto retrieve the full execution plan including trace.
[0.4.1] - 2025-12-19¶
Added¶
Embedded Database Support: Full support for connection schemes
mem://,surrealkv://, andfile://utilizing the underlying SDK’s native embedded capabilities.Sync API Parity: Added
Document.update_sync(),Document.save_sync(),Document.refresh_sync(), andRelationDocument.update_sync()to match async capabilities.Data Type Compliance: Core fields (
DurationField,RangeField,GeometryField,TableField,RecordIDField) now natively support and preservesurrealdbSDK objects (Duration,Range,Geometry,Table,RecordID).
Changed¶
Strict Return Types: Fields like
RecordIDFieldnow returnsurrealdb.RecordIDobjects instead of strings, improving type safety.Improved Serialization: Refactored
Document.saveandDocument.updatelogic to share a unified serialization creation pipeline, fixing CBOR errors withDatetimeobjects.Refactoring: Merged
document_update.pyintodocument.pyfor cleaner architecture.BaseQuerySet: Updated to remove legacy dependencies and improve query building robustness.
Fixed¶
CBOR Serialization: Fixed
ValueError: CBOR text data type must be strwhen savingdatetimeobjects.ReferenceField Bug: Fixed issue where
ReferenceFieldwas incorrectly convertingRecordIDobjects to strings during serialization.Geometry Validation: Enhanced
GeometryFieldto strictly validate closed linear rings for Polygons.Default Values: Fixed issue where default values were not persisted when creating documents with manually specified IDs.
Enhanced¶
Immutable Filtering:
BaseQuerySet.filter()now returns a new queryset instance, preventing accidental mutation of the original queryset.Advanced
QObject Handling: Thefiltermethod now correctly handles complex, nestedQobjects for more powerful and intuitive query construction.Combined Queries:
filter()now supports passing both aQobject and keyword arguments simultaneously, allowing for more flexible query building.Robust
to_where_clause: TheQ.to_where_clause()method has been rewritten to correctly handle nestedQobjects and generate validWHEREclauses for complex queries.
Fixed¶
Corrected the
VALUEkeyword toDEFAULTin the schema generation for document fields.Improved the
serialize_http_safefunction to correctly handleIsoDateTimeWrapperobjects, preventing potential issues with datetime serialization.
[0.3.0] - 2025-09-01¶
Added¶
Expression and query building
Expr is now a single class with a working CASE builder:
Expr.case().when(...).else_(...).alias(...)Expr.var(name)for$varsandExpr.raw(...)for trusted fragmentsString functions aligned with SurrealDB v2:
string::starts_with,string::ends_with,string::contains,string::matches
Escaping utilities
Public
escape_literalandescape_identifier; builders use these consistently
Aggregation and materialized views
AggregationPipeline: response normalization (returns list of row dicts), safe escaping in
match()/having(), and injectsGROUP BY/GROUP ALLwhen neededMaterialized functions updated for v2: replaced
array::collectwitharray::group; hardenedDistinct,GroupConcatfor scalar inputs;DistinctCountIfnow usesarray::len(array::group(IF cond THEN [field] ELSE [] END))
Connection and observability
ContextVar‑backed per‑task default connection:
set_default_connection/get_default_connectionConnection pooling with validation, idle pruning, retries/backoff
OperationQueue with backpressure policies (block | drop_oldest | error) and metrics
Optional OpenTelemetry spans around queries/transactions (enabled if OTEL is installed)
Example script:
example_scripts/connection_and_observability_example.py
Graph and live updates
QuerySet.traverse(path, max_depth=None, unique=True) to project graph traversals
QuerySet.live(…): async generator for LIVE subscriptions (requires direct async ws connection)
Example script:
example_scripts/graph_and_live_example.py
RelationDocument helpers
RelationDocument.find_by_in_documents(...)and sync variant for batch inbound lookups
Document/Relation updates
Added
update()andupdate_sync()on Document and RelationDocument for partial updates without data loss
Changed¶
Centralized escaping in BaseQuerySet, AggregationPipeline, and Expr; removed ad‑hoc json.dumps usage for literals
SurrealQL builder ensures
FETCHis emitted as the last clause to avoid parse errorsLIVE subscription path: replaced debug print statements with logger.debug to avoid leaking to stdout and to integrate with standard logging
Docstring improvements across key APIs (e.g., QuerySet.live()) for richer IDE hints
Fixed¶
BaseQuerySet condition building now uses
escape_literalconsistently, including URL handling and arrays; preserves unquoted RecordIDs in INSIDE/NOT INSIDE arraysMaterialized array functions migrated to v2 semantics;
DistinctCountIfproduces correct distinct counts without function argument errorsSchema regex assertions now use
string::matches($value, pattern)with proper literal escapingAggregationPipeline results are normalized (no more
'str'.geterrors in examples)Correct formatting for INSIDE/NOT INSIDE arrays containing RecordIDs (record ids unquoted)
Document.save() automatically uses
update()for RelationDocument to prevent unintended field removalFixed TypeError in document update isinstance check
Notes¶
LIVE queries currently require a direct async websocket client (pooling client does not support LIVE)
returning=is supported onQuerySet.update(...); other mutations may follow in a future release
[0.2.1] - 2025-07-02¶
Added¶
Query Expression System: Advanced query building with Q objects and QueryExpression
Q objects for complex boolean logic supporting AND (&), OR (|), and NOT (~) operations
QueryExpression class for comprehensive query building with FETCH, ORDER BY, GROUP BY, LIMIT, and START clauses
objects(query) syntax - Alternative to filter() allowing direct query object passing:
User.objects(Q(active=True))filter(query) enhancement - Now accepts Q objects and QueryExpressions in addition to kwargs
Raw query support with
Q.raw()for custom SurrealQL WHERE clausesFETCH integration - QueryExpression with FETCH automatically dereferences related documents
Django-style operators - Support for field__operator syntax (gt, lt, gte, lte, ne, in, contains, startswith, endswith, regex)
Method chaining - Full compatibility with existing queryset methods (limit, order_by, fetch, etc.)
Synchronous support - All query expression features work with both async and sync operations
Fixed¶
String function compatibility - Updated to use correct SurrealDB v2.x string function names (
string::starts_withinstead ofstring::startsWith,string::ends_withinstead ofstring::endsWith)
Added (Continued)¶
DataGrid API Support: Comprehensive frontend integration for data table libraries
Efficient SurrealDB query optimization replacing Python-based filtering with database-native operations
Support for BootstrapTable.js format (maintaining backward compatibility with existing APIs)
DataTables.js parameter conversion and response formatting
Pagination, sorting, filtering, and search functionality optimized at the database level
get_grid_data()andget_grid_data_sync()helper functions for easy route integrationDataGridQueryBuilderclass for building complex filtered queriesParameter conversion utilities:
parse_datatables_params()andformat_datatables_response()Performance benefits: Only fetch required data, leverage SurrealDB indexes, reduce memory usage
Drop-in replacement for existing route logic - reduces 50+ lines of filtering code to a single function call
[0.2.0] - 2024-06-28¶
Added¶
Implemented advanced connection management features:
Connection pooling with configurable pool size, connection reuse, validation, and cleanup
Integration of connection pools with Document models for seamless use in async applications
Connection timeouts and retries with exponential backoff
Automatic reconnection with event-based triggers and operation queuing
Connection string parsing with support for connection options
Pagination support across all query methods with
page(number, size)methodMade dependencies optional: signals (blinker) and jupyter (notebook) can now be installed separately
Added
PaginationResultclass for enhanced pagination with metadataAdded new field types: EmailField, URLField, IPAddressField, SlugField, ChoiceField
Added proper logging system with SurrealEngineLogger class
Added native SurrealDB type support with LiteralField and RangeField
Enhanced SetField to ensure uniqueness during validation
Added TimeSeriesField for time series data with metadata support
Added materialized views support with MaterializedView class and Document.create_materialized_view method
Enhanced materialized views with support for aggregation functions (count, mean, sum, min, max, array_collect) and custom field selection
Added
get_raw_query()method to BaseQuerySet to get the raw query string without executing it, allowing for manual execution or modification of queriesAdded
execute_raw_query()andexecute_raw_query_sync()methods to MaterializedView to execute raw queries against materialized viewsAdded field-level indexing with
indexed,unique,search, andanalyzerparametersAdded support for multi-field indexes with the
index_withparameterAdded aggregation pipelines with the
AggregationPipelineclass for complex data transformationsAdded additional aggregation functions: Median, StdDev, Variance, Percentile, Distinct, GroupConcat
Added automatic reference resolution with
Document.get(dereference=True)andDocument.resolve_references()methodsAdded JOIN-like operations with
QuerySet.join()method for efficient retrieval of referenced documentsEnhanced RelationField with
get_related_documents()method for bidirectional relation navigationPERFORMANCE IMPROVEMENT: Updated all reference/dereference code to use SurrealDB’s native FETCH clause instead of manual resolution:
ReferenceField.from_db()now handles fetched documents automaticallyRelationField.from_db()now handles fetched relations automaticallyDocument.resolve_references()uses FETCH queries for efficient bulk resolutionDocument.get()withdereference=Trueuses FETCH for single-query reference resolutionQuerySet.join()methods use FETCH clauses internally for better performanceMaintains full backward compatibility with fallback to manual resolution if FETCH fails
MAJOR PERFORMANCE ENHANCEMENT: Implemented comprehensive query performance optimizations:
Auto-optimization for
id__infilters: Automatically convertsfilter(id__in=[...])to direct record access syntaxSELECT * FROM user:id1, user:id2, user:id3for up to 3.4x faster queriesNew convenience methods: Added
get_many(ids)andget_range(start_id, end_id)for optimized bulk record retrieval using direct record access and range syntaxSmart filter optimization: Automatic detection of ID range patterns (
id__gte+id__lte) and conversion to optimized range queriesSELECT * FROM table:start..=endDeveloper experience tools:
explain()andexplain_sync()methods for query execution plan analysissuggest_indexes()method for intelligent index recommendations based on query patterns
Optimized bulk operations: Enhanced
update()anddelete()methods with direct record access for bulk ID operations, improving performance for large datasetsUniversal ID support: All optimizations work seamlessly with both auto-generated IDs and custom IDs, maintaining backward compatibility
Changed¶
Updated README.md with instructions for installing optional dependencies
Improved pagination ergonomics with the
page(number, size)methodMarked “Implement schema registration with SurrealDB” as completed in tasks.md
Removed JSONField and replaced it with DictField for better functionality and consistency
Refactored fields.py into a directory structure with separate modules for better organization and maintainability
Fixed¶
Fixed pagination support to work with all query methods, not just filter()
Enhanced ReferenceField to properly handle RecordID objects
Fixed DictField nested field access in queries using double underscore syntax (e.g.,
settings__theme="dark")Added support for nested fields in DictFields when using schemafull tables
Fixed IPAddressField to properly handle the ‘version’ parameter for backward compatibility
Fixed issue with docstring comments in create_table method causing parsing errors
Removed debug print statements and commented-out code for cleaner codebase
CRITICAL FIX: Fixed ID formatting issue in upsert operations where numeric string IDs like “testdoc:123” were being stored incorrectly, causing retrieval failures
[0.1.0] - 2023-05-12¶
Added¶
Initial release of SurrealEngine
Basic document model with field validation
Query functionality with filtering and pagination
Schemaless API for flexible database access
Support for both synchronous and asynchronous operations
Connection management with connection registry
Transaction support
Relation management with graph traversal