Skip to main content

A unified, multi-engine async ORM for Python (MongoDB, PostgreSQL, MySQL, SQLite)

Project description

TabernacleORM 2.1.5 🐍⚡

The Async, Pydantic-powered ORM for Python.

TabernacleORM is a modern, lightweight, and fully async Object-Relational Mapper (ORM) designed for FastAPI and modern Python applications. It supports PostgreSQL, MySQL, SQLite, and MongoDB with a unified, expressive API.

Features

  • Pydantic V2 Native: Models are Pydantic models. Automatic validation, JSON serialization, and OpenAPI schema generation.
  • Fully Async: Built from the ground up for asyncio. No blocking IO.
  • Unified API: Switch between SQL and NoSQL databases without changing your business logic.
  • Relationships: OneToMany, ManyToMany, ForeignKey with lazy loading.
  • Fluent Query Builder: Write expressive queries like User.filter(User.age > 18).
  • Lifecycle Hooks: before_save, after_create, etc., for powerful automation.
  • Stateless Sessions: Thread-safe and concurrency-safe session management.
  • Read/Write Splitting: Native support for replicas and high availability.
  • CLI & Migrations: Django-style migration system for both SQL and NoSQL.
  • Weighted Load Balancing: Distribute traffic across replicas with ease.

Installation

pip install tabernacleorm
# For specific engines:
pip install tabernacleorm[postgresql]
pip install tabernacleorm[mysql]
pip install tabernacleorm[mongodb]

CLI & Migrations 🚀

TabernacleORM includes a powerful CLI to manage migrations for all supported databases.

# Initialize project
tabernacle init

# Create a new migration based on your models
tabernacle makemigrations "initial_schema"

# Apply pending migrations
tabernacle migrate

# Rollback last migration
tabernacle rollback

Quickstart

1. Define your Models

Since Tabernacle models are Pydantic models, defining schemas is intuitive:

from typing import Optional
from tabernacleorm import Model, connect
from tabernacleorm.fields import StringField, IntegerField, ForeignKey, OneToMany

# Connect to DB with auto table creation
connect("sqlite:///:memory:", auto_create=True)

class User(Model):
    name: str = StringField(max_length=50)
    age: int = IntegerField(default=18)
    
    # Relationships
    posts: list["Post"] = OneToMany("Post", back_populates="author_id")

    # Lifecycle Hooks
    async def before_save(self):
        self.name = self.name.capitalize()

class Post(Model):
    title: str = StringField()
    content: str = StringField()
    author_id: int = ForeignKey("User")

2. Create and Query

import asyncio

async def main():
    # Create Tables (Handled by auto_create=True, or use migrations in prod)
    # await User.get_engine().executeRaw(User.get_create_table_sql())

    # Create Records
    user = await User.create(name="alice", age=30)
    await Post.create(title="Hello World", content="My first post", author_id=user.id)

    # Fluent Querying (Async)
    users = await User.filter(User.age > 20).all()
    
    # Eager Loading (New!)
    # Fetch users with their 'posts' in one go
    users_with_posts = await User.filter(User.age > 20).include("posts").all()

    # Lazy Loading (New!)
    my_posts = await user.fetch_related("posts")

    # Complex Filtering
    posts = await Post.filter(Post.title.startswith("Hello")).limit(5).all()

asyncio.run(main())

Documentation

New in 2.1.5: Weighted Load Balancing ⚖️

You can now assign weights to read replicas to distribute traffic according to server capacity.

db = connect(
    engine="postgresql",
    write={"url": "postgresql://master:5432/db"},
    read=[
        # Heavy server gets 70% of traffic
        {"url": "postgresql://huge-replica:5432/db", "weight": 70},
        # Smaller server gets 30%
        {"url": "postgresql://small-replica:5432/db", "weight": 30}
    ]
)

Advanced Features

Transactions

Use the session context manager for safe transactions:

engine = User.get_engine()
async with engine.transaction() as session:
    user = await User.create(name="Bob", age=25)
    # Pass session to save() to participate in transaction
    await Post.create(title="Intro", content="...", author_id=user.id, session=session)

Hooks

Available hooks:

  • before_save / after_save
  • before_create / after_create
  • before_delete / after_delete
class user(Model):
    password: str
    
    async def before_save(self):
        if not self.password.startswith("hash:"):
            self.password = f"hash:{self.password}"

Relationships

Define relationships using OneToMany, ManyToMany, or standard ForeignKey. Use await instance.fetch_related("field_name") to load them efficiently.


Built with ❤️ by the Tabernacle Team.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tabernacleorm-2.1.5.tar.gz (19.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tabernacleorm-2.1.5-py3-none-any.whl (61.4 kB view details)

Uploaded Python 3

File details

Details for the file tabernacleorm-2.1.5.tar.gz.

File metadata

  • Download URL: tabernacleorm-2.1.5.tar.gz
  • Upload date:
  • Size: 19.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for tabernacleorm-2.1.5.tar.gz
Algorithm Hash digest
SHA256 2a2633bff36317fe6ed693fcc4ddea455ef9c4364029db74c509ba9db264d921
MD5 63488cbcff1ccd3eb418d4c83faf928d
BLAKE2b-256 973b344edcd5d515e4e94fc69f13d1500bf76012c8cb7e6ceec18700654a61ff

See more details on using hashes here.

File details

Details for the file tabernacleorm-2.1.5-py3-none-any.whl.

File metadata

  • Download URL: tabernacleorm-2.1.5-py3-none-any.whl
  • Upload date:
  • Size: 61.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for tabernacleorm-2.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ae6d0b91b68bcad841535db3253b6914b7c09e8cfaa95a7ff9e901619b56de52
MD5 e06f82ddce9b5199cc611a26a9830487
BLAKE2b-256 4bf544fc8b3a600c56da5284f6a0c71195e6a6f99e27fcd8992fa77b2f253a31

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page