Type-Safe Modern ORM - Data in 3D
Project description
██████╗ █████╗ ████████╗ █████╗ ██╗ ██╗ ██████╗ ██╗ ██╗███████╗██╗
██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗██║ ██║██╔═══██╗╚██╗██╔╝██╔════╝██║
██║ ██║███████║ ██║ ███████║██║ ██║██║ ██║ ╚███╔╝ █████╗ ██║
██║ ██║██╔══██║ ██║ ██╔══██║╚██╗ ██╔╝██║ ██║ ██╔██╗ ██╔══╝ ██║
██████╔╝██║ ██║ ██║ ██║ ██║ ╚████╔╝ ╚██████╔╝██╔╝ ██╗███████╗███████╗
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝
🗄️ Type-Safe Modern ORM 🗄️
Data in 3D - Where Database Queries Feel Like Magic
Quick Start • Features • Examples • Documentation
🌟 What is DATAVOXEL?
DATAVOXEL is a revolutionary ORM that thinks in 3 dimensions: Type Safety, Developer Experience, and Performance. Built on SQLAlchemy but with a modern twist, it makes database operations feel natural and intuitive.
from datavoxel import Model, Query
class User(Model):
__table__ = "users"
id: int
name: str
email: str
created_at: datetime
# Type-safe queries with IDE autocomplete!
users = Query(User).where(User.age > 18).order_by(User.name).limit(10).all()
# 🎯 Your IDE knows exactly what type 'users' is!
✨ Key Features
📦 Installation
# Basic installation (SQLite support)
pip install datavoxel
# With PostgreSQL support
pip install datavoxel[postgres]
# With MySQL support
pip install datavoxel[mysql]
# With all database drivers
pip install datavoxel[all]
🎯 Quick Start
Define Your Models
from datavoxel import Model
from datetime import datetime
from typing import Optional
class User(Model):
__table__ = "users"
__database__ = "myapp"
id: int
username: str
email: str
is_active: bool = True
created_at: datetime = datetime.now()
bio: Optional[str] = None
Simple CRUD Operations
# Create
user = User(username="john_doe", email="john@example.com")
await user.save()
# Read
user = await User.get(id=1)
users = await User.filter(is_active=True).all()
# Update
user.email = "newemail@example.com"
await user.save()
# Delete
await user.delete()
Advanced Queries
from datavoxel import Query, Q
# Complex WHERE clauses
active_users = await Query(User).where(
(User.is_active == True) &
(User.created_at > datetime(2024, 1, 1))
).all()
# Joins
class Post(Model):
__table__ = "posts"
user_id: int
title: str
content: str
posts_with_users = await Query(Post).join(
User, Post.user_id == User.id
).select(Post.title, User.username).all()
# Aggregations
from datavoxel import Count, Avg
user_count = await Query(User).aggregate(Count(User.id))
avg_age = await Query(User).aggregate(Avg(User.age))
🏗️ Architecture
graph TB
A[Your Application] --> B[DATAVOXEL ORM]
B --> C{Query Builder}
B --> D{Model Manager}
B --> E{Migration Engine}
C --> F[Type Checker]
C --> G[SQL Generator]
D --> H[CRUD Operations]
D --> I[Relationships]
E --> J[Schema Diff]
E --> K[Auto Migrate]
F --> L[SQLAlchemy Core]
G --> L
H --> L
I --> L
J --> L
K --> L
L --> M{Database Driver}
M --> N[PostgreSQL]
M --> O[MySQL]
M --> P[SQLite]
style B fill:#2196F3
style L fill:#4CAF50
🔥 Advanced Features
Relationships
class Author(Model):
__table__ = "authors"
id: int
name: str
class Book(Model):
__table__ = "books"
id: int
title: str
author_id: int
# Define relationship
author = Relation(Author, foreign_key="author_id")
# Use relationships
book = await Book.get(id=1)
author = await book.author # Automatically fetches author
print(f"{book.title} by {author.name}")
Transactions
from datavoxel import transaction
async with transaction():
user = User(username="alice")
await user.save()
post = Post(title="First Post", user_id=user.id)
await post.save()
# Both saved or both rolled back together!
Query Optimization
# Eager loading (N+1 query prevention)
books = await Query(Book).prefetch(Book.author).all()
# Only 2 queries instead of N+1!
# Select only needed fields
users = await Query(User).only(User.id, User.username).all()
# Smaller result set = faster queries
# Bulk operations
await User.bulk_create([
User(username="user1", email="user1@example.com"),
User(username="user2", email="user2@example.com"),
])
Custom Queries
# Raw SQL when needed
results = await Query.raw("""
SELECT users.name, COUNT(posts.id) as post_count
FROM users
LEFT JOIN posts ON users.id = posts.user_id
GROUP BY users.id
HAVING post_count > 10
""")
📊 Comparison with Other ORMs
| Feature | DATAVOXEL | SQLAlchemy | Django ORM | Peewee | Tortoise |
|---|---|---|---|---|---|
| Type Safety | ✅ Full | ⚠️ Partial | ❌ No | ❌ No | ⚠️ Partial |
| Async Support | ✅ Native | ✅ Yes | ⚠️ Limited | ❌ No | ✅ Yes |
| Learning Curve | 🟢 Easy | 🔴 Hard | 🟢 Easy | 🟢 Easy | 🟡 Medium |
| Auto Migrations | ✅ Built-in | ⚠️ Alembic | ✅ Yes | ❌ No | ✅ Yes |
| IDE Support | ⚡⚡⚡⚡⚡ | ⚡⚡ | ⚡⚡ | ⚡⚡ | ⚡⚡⚡ |
| Performance | ⚡⚡⚡⚡ | ⚡⚡⚡⚡⚡ | ⚡⚡⚡ | ⚡⚡⚡⚡ | ⚡⚡⚡⚡ |
🎨 Real-World Examples
FastAPI Integration
from fastapi import FastAPI, Depends
from datavoxel import Model, Query
app = FastAPI()
class User(Model):
__table__ = "users"
id: int
username: str
email: str
@app.get("/users/{user_id}")
async def get_user(user_id: int):
user = await User.get(id=user_id)
return user.dict() # Automatic serialization!
@app.get("/users")
async def list_users(skip: int = 0, limit: int = 10):
users = await Query(User).offset(skip).limit(limit).all()
return [user.dict() for user in users]
Data Pipeline
from datavoxel import Model, transaction
import asyncio
class RawData(Model):
__table__ = "raw_data"
id: int
data: str
class ProcessedData(Model):
__table__ = "processed_data"
id: int
result: str
async def process_data():
raw_items = await Query(RawData).filter(processed=False).all()
async with transaction():
for item in raw_items:
# Process data
result = transform(item.data)
# Save result
processed = ProcessedData(result=result)
await processed.save()
# Mark as processed
item.processed = True
await item.save()
Multi-Tenant App
from datavoxel import Model, set_schema
class Tenant(Model):
__table__ = "tenants"
id: int
schema_name: str
class User(Model):
__table__ = "users"
__schema_bound__ = True # Uses current schema
id: int
name: str
async def get_tenant_users(tenant_id: int):
tenant = await Tenant.get(id=tenant_id)
# Switch to tenant schema
set_schema(tenant.schema_name)
# Query tenant-specific data
users = await Query(User).all()
return users
📚 Documentation
🗺️ Roadmap
✅ Version 0.1.0 (Current)
- Type-safe models
- Basic CRUD operations
- Query builder
- Async support
🚧 Version 0.2.0 (Coming Soon)
- Auto migrations
- Relationship support
- Connection pooling
- Query caching
🔮 Version 0.3.0 (Planned)
- Advanced relationships (M2M, polymorphic)
- Full-text search
- Database sharding
- Performance monitoring
- GraphQL integration
🤝 Contributing
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
📜 License
MIT License - see LICENSE file for details.
👤 Author
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file datavoxel-0.2.0.tar.gz.
File metadata
- Download URL: datavoxel-0.2.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1196d588e174df59d18ec9a7939a70d271aac8053622a43c974b955e5d9bc749
|
|
| MD5 |
6489c5dbd5288a76b531b8b7bd43f6bf
|
|
| BLAKE2b-256 |
ea530cbe5dc2099e1b0ff37c1eec2c37da997d748fbb699798e024ccf563e65b
|
File details
Details for the file datavoxel-0.2.0-py3-none-any.whl.
File metadata
- Download URL: datavoxel-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9703bb0c45f04168b84b1cf9840fab21a543186478551f1206bef37f0e915544
|
|
| MD5 |
c317d9ccb7f4d51cb3c83690ac687a74
|
|
| BLAKE2b-256 |
083fd466b8e134231bc03d8f9fd7ecfa38d1c5ebfc27dea62c3bdf568f69066b
|