A simple and intuitive Pydantic-based ORM for SurrealDB, providing both synchronous and asynchronous operations.
- 🔄 Both synchronous and asynchronous operations
- 🏗️ Built on top of Pydantic for robust data validation
- 🚀 Simple and intuitive API
- 📝 Type hints and comprehensive documentation
- 🔍 Automatic timestamp handling for created/updated fields
- 🎯 Support for complex queries and relationships
pip install surrantic
from datetime import datetime
from typing import Optional
from surrantic import ObjectModel
from surrealdb import RecordID
class User(ObjectModel):
table_name = "user" # Define the table name in SurrealDB
name: str
email: str
age: Optional[int] = None
# Async Usage
async def main():
# Create a new user
user = User(name="John Doe", email="[email protected]", age=30)
await user.asave() # Saves to SurrealDB
print(f"User created with ID: {user.id}")
# Fetch all users
all_users = await User.aget_all()
for user in all_users:
print(f"Found user: {user.name}")
# Get a specific user
user_id = "user:123" # or RecordID object
user = await User.aget(user_id)
if user:
print(f"Found user: {user.name}")
# Delete a user
await user.adelete()
# Synchronous Usage
def sync_example():
user = User(name="Jane Doe", email="[email protected]")
user.save() # Synchronous save
# Get all users
users = User.get_all()
# Delete user
user.delete()
# Get all users ordered by name
users = await User.aget_all(order_by="name", order_direction="ASC")
Created and updated timestamps are automatically handled:
user = User(name="John", email="[email protected]")
await user.asave()
print(f"Created at: {user.created}") # Automatically set
print(f"Updated at: {user.updated}") # Automatically set
When using RecordID
fields in your models, you should add a field serializer to properly convert them to strings when using model_dump()
. Here's an example:
from pydantic import field_serializer
from surrealdb import RecordID
class User(ObjectModel):
table_name = "user"
name: str
class Post(ObjectModel):
table_name = "post"
title: str
author: RecordID # Reference to a User
@field_serializer('author')
def serialize_author(self, author: RecordID) -> str:
return str(author)
Note: The base ObjectModel
already handles the serialization of the id
field.
By default, Surrantic uses environment variables for database configuration:
SURREAL_ADDRESS=ws://localhost:8000
SURREAL_USER=root
SURREAL_PASS=root
SURREAL_NAMESPACE=test
SURREAL_DATABASE=test
You can also override these settings directly in your code using SurranticConfig
:
from surrantic import SurranticConfig
SurranticConfig.configure(
address="ws://localhost:8000",
user="root",
password="root",
namespace="test",
database="test",
debug=True # Enable query logging
)
When debug mode is enabled, all queries and their results will be logged:
DEBUG:surrantic.base:Query: SELECT * FROM user ORDER BY created DESC
DEBUG:surrantic.base:Result: [{"id": "user:123", "name": "John Doe", "email": "[email protected]"}]
Surrantic includes configurable logging:
from surrantic.logging_config import setup_logging
import logging
# Console only logging
setup_logging(level=logging.DEBUG)
# Console and file logging
setup_logging(level=logging.INFO, log_file="surrantic.log")
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Python 3.11+
- pydantic >= 2.0.0
- surrealdb >= 0.3.0