Connection Management¶
SurrealEngine provides flexible connection management supporting various connection schemes, connection pooling, retry logic, and both synchronous and asynchronous operations.
Creating Connections¶
Basic Connection¶
Create a connection to a remote SurrealDB instance:
from surrealengine import create_connection
# Async connection
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="production",
username="root",
password="root",
async_mode=True,
make_default=True
)
await connection.connect()
Synchronous Connection¶
For synchronous applications:
# Sync connection
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="production",
username="root",
password="root",
async_mode=False,
make_default=True
)
connection.connect_sync()
Connection Schemes¶
SurrealEngine supports multiple connection schemes for different deployment scenarios.
WebSocket Connections¶
Standard WebSocket connections for remote servers:
# WebSocket (ws://)
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb"
)
# Secure WebSocket (wss://)
connection = create_connection(
url="wss://db.example.com/rpc",
namespace="myapp",
database="mydb"
)
HTTP Connections¶
HTTP/HTTPS connections:
# HTTP connection
connection = create_connection(
url="http://localhost:8000",
namespace="myapp",
database="mydb"
)
# HTTPS connection
connection = create_connection(
url="https://db.example.com",
namespace="myapp",
database="mydb"
)
Embedded Databases (v0.4.1+)¶
SurrealEngine now supports embedded database schemes for local, in-memory, and file-based databases using the SurrealDB SDK’s native embedded capabilities.
Memory Database¶
In-memory database - perfect for testing or temporary data:
from surrealengine import create_connection
# In-memory database
connection = create_connection(
url="mem://",
namespace="test",
database="temp",
async_mode=True,
make_default=True
)
await connection.connect()
# Data is lost when connection closes
# Perfect for unit tests!
Use cases: - Unit testing - Temporary data processing - Development without persistent storage - Fast prototyping
File-Based Database¶
Persistent file-based database:
# File-based database
connection = create_connection(
url="file:///path/to/database/directory",
namespace="myapp",
database="mydb",
async_mode=True,
make_default=True
)
await connection.connect()
# Data persists to the file system
# No separate database server needed!
Use cases: - Desktop applications - Edge computing - Offline-first applications - Single-user applications - Development and testing
SurrealKV Database¶
High-performance key-value store:
# SurrealKV database
connection = create_connection(
url="surrealkv:///path/to/database",
namespace="myapp",
database="mydb",
async_mode=True,
make_default=True
)
await connection.connect()
Use cases: - High-performance applications - Low-latency requirements - Embedded systems - IoT devices
Embedded Database Examples¶
Complete examples for embedded databases:
import asyncio
from surrealengine import Document, StringField, IntField, create_connection
class User(Document):
name = StringField(required=True)
age = IntField()
class Meta:
collection = "users"
async def test_with_memory_db():
"""Test with in-memory database"""
conn = create_connection(
url="mem://",
namespace="test",
database="test",
async_mode=True,
make_default=True
)
await conn.connect()
# Create and query data
user = User(name="Alice", age=30)
await user.save()
users = await User.objects.all()
print(f"Found {len(users)} users")
async def app_with_file_db():
"""Application with file-based database"""
conn = create_connection(
url="file:///var/lib/myapp/db",
namespace="myapp",
database="production",
async_mode=True,
make_default=True
)
await conn.connect()
# Your application logic here
# Data persists between runs
def sync_app_with_embedded_db():
"""Synchronous app with embedded database"""
conn = create_connection(
url="file://./local_db",
namespace="myapp",
database="mydb",
async_mode=False,
make_default=True
)
conn.connect_sync()
# Synchronous operations
user = User(name="Bob", age=25)
user.save_sync()
Connection Pooling¶
Enable connection pooling for better performance with concurrent requests:
# With connection pooling
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb",
async_mode=True,
use_pool=True,
pool_size=10,
make_default=True
)
await connection.connect()
Note
Connection pooling is not supported with LIVE queries. For LIVE subscriptions,
use use_pool=False to get a direct websocket connection.
Pool Options¶
Configure connection pool behavior:
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb",
async_mode=True,
use_pool=True,
pool_size=20, # Maximum connections in pool
pool_max_idle=300, # Seconds before idle connection is closed
pool_validation=True, # Validate connections before use
make_default=True
)
Retry and Timeout¶
Configure retry logic and timeouts:
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb",
async_mode=True,
retry_limit=3, # Number of retry attempts
initial_delay=0.5, # Initial retry delay in seconds
backoff=2.0, # Backoff multiplier
timeout=30.0, # Connection timeout in seconds
make_default=True
)
Default Connections¶
Set a default connection for all operations:
# Create and set as default
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb",
async_mode=True,
make_default=True # Sets as default
)
await connection.connect()
# Now all operations use this connection by default
user = User(name="Alice")
await user.save() # Uses default connection
# Query without explicit connection
users = await User.objects.all()
Multiple Connections¶
Manage multiple database connections:
# Primary database
primary = create_connection(
url="ws://primary.example.com/rpc",
namespace="myapp",
database="production",
async_mode=True,
make_default=True
)
await primary.connect()
# Analytics database
analytics = create_connection(
url="ws://analytics.example.com/rpc",
namespace="myapp",
database="analytics",
async_mode=True,
make_default=False
)
await analytics.connect()
# Use default connection
user = User(name="Alice")
await user.save() # Saves to primary
# Use specific connection
await user.save(connection=analytics) # Saves to analytics
Connection Registry¶
Retrieve connections from the registry:
from surrealengine import ConnectionRegistry
# Get default async connection
conn = ConnectionRegistry.get_default_connection(async_mode=True)
# Get default sync connection
conn = ConnectionRegistry.get_default_connection(async_mode=False)
Connection Context Managers¶
Use connections with context managers for automatic cleanup:
async def process_data():
connection = create_connection(
url="ws://localhost:8000/rpc",
namespace="myapp",
database="mydb",
async_mode=True
)
async with connection:
# Connection automatically connects and closes
user = User(name="Alice")
await user.save()
Best Practices¶
Use embedded databases for local applications (v0.4.1+):
# Desktop app - use file:// conn = create_connection(url="file://./app_data/db", ...) # Testing - use mem:// conn = create_connection(url="mem://", ...)
Set make_default=True for primary connection:
primary = create_connection(..., make_default=True)
Use connection pooling for web applications:
conn = create_connection(..., use_pool=True, pool_size=20)
Disable pooling for LIVE queries:
conn = create_connection(..., use_pool=False) # Required for LIVE
Configure appropriate timeouts and retries:
conn = create_connection( ..., timeout=30.0, retry_limit=3 )
Use HTTPS/WSS in production:
conn = create_connection(url="wss://db.example.com/rpc", ...)
Choose the right scheme for your use case:
ws:///wss://- Remote database serverhttp:///https://- HTTP-based connectionsmem://- Testing and temporary data (v0.4.1+)file://- Desktop/offline apps (v0.4.1+)surrealkv://- High-performance embedded (v0.4.1+)
Connection Lifecycle¶
Typical connection lifecycle:
# 1. Create connection
connection = create_connection(...)
# 2. Connect
await connection.connect()
# 3. Use connection
user = User(name="Alice")
await user.save()
# 4. Close connection (optional, but recommended)
await connection.close()
Health Checks¶
Monitor connection health:
# Check if connected
if connection.is_connected():
print("Connected to database")
# Ping the database
await connection.ping()
Troubleshooting¶
Common Connection Issues¶
Connection refused:
Check that SurrealDB is running
Verify the URL and port
Check firewall settings
Authentication failed:
Verify username and password
Check namespace and database names
Ensure user has proper permissions
Timeout errors:
Increase timeout setting
Check network connectivity
Verify database server is responsive
Pool exhausted:
Increase pool_size
Check for connection leaks
Ensure connections are being released
LIVE queries not working:
Set
use_pool=FalseUse async websocket connection
Check SurrealDB version supports LIVE
Migration Guide¶
Embedded Database Support (v0.4.1+)¶
New embedded database schemes are now available:
# NEW (v0.4.1+) - Embedded databases
conn = create_connection(url="mem://", ...)
conn = create_connection(url="file:///path/to/db", ...)
conn = create_connection(url="surrealkv:///path/to/db", ...)
# Still supported - Remote databases
conn = create_connection(url="ws://localhost:8000/rpc", ...)