Back Original

Show HN: Oxyde – Pydantic-native async ORM with a Rust core

Logo

Oxyde ORM is a type-safe, Pydantic-centric asynchronous ORM with a high-performance Rust core designed for clarity, speed, and reliability.

Inspired by the elegance of Django's ORM, Oxyde focuses on explicitness over magic, providing a modern developer-friendly workflow with predictable behavior and strong typing throughout.

PyPI Downloads


Heads up! Oxyde is a young project under active development. The API may evolve between minor versions. Feedback, bug reports, and ideas are very welcome. Feel free to open an issue!

  • Django-style API — Familiar Model.objects.filter() syntax
  • Pydantic v2 models — Full validation, type hints, serialization
  • Async-first — Built for modern async Python with asyncio
  • Rust performance — SQL generation and execution in native Rust
  • Multi-database — PostgreSQL, SQLite, MySQL support
  • Transactionstransaction.atomic() context manager with savepoints
  • Migrations — Django-style makemigrations and migrate CLI

Benchmarks vs popular Python ORMs (avg ops/sec, higher is better):

Database Oxyde Tortoise Piccolo Django SQLAlchemy SQLModel Peewee
PostgreSQL 1,475 888 932 736 445 431 80
MySQL 1,239 794 714 536 505 461
SQLite 2,525 1,882 469 1,294 588 567 548

Full benchmark report: Documentation

This creates oxyde_config.py with your database settings and model paths.

# models.py
from oxyde import Model, Field

class User(Model):
    id: int | None = Field(default=None, db_pk=True)
    name: str
    email: str = Field(db_unique=True)
    age: int | None = Field(default=None)

    class Meta:
        is_table = True
oxyde makemigrations
oxyde migrate
import asyncio
from oxyde import db
from models import User

async def main():
    await db.init(default="sqlite:///app.db")

    # Create
    user = await User.objects.create(name="Alice", email="alice@example.com", age=30)

    # Read
    users = await User.objects.filter(age__gte=18).all()
    user = await User.objects.get(id=1)

    # Update
    user.age = 31
    await user.save()

    # Delete
    await user.delete()

    await db.close()

asyncio.run(main())
from oxyde.db import transaction

async with transaction.atomic():
    user = await User.objects.create(name="Alice", email="alice@example.com")
    await Profile.objects.create(user_id=user.id)
    # Auto-commits on success, rolls back on exception
from fastapi import FastAPI
from oxyde import db

app = FastAPI(
    lifespan=db.lifespan(
        default="postgresql://localhost/mydb",
    )
)

@app.get("/users")
async def get_users():
    return await User.objects.filter(is_active=True).all()
Database Min Version Status Notes
PostgreSQL 12+ Full RETURNING, UPSERT, FOR UPDATE/SHARE, JSON, Arrays
SQLite 3.35+ Full RETURNING, UPSERT, WAL mode by default
MySQL 8.0+ Full UPSERT via ON DUPLICATE KEY, FOR UPDATE/SHARE

Connection URLs:

postgresql://user:password@localhost:5432/database
sqlite:///path/to/database.db
sqlite:///:memory:
mysql://user:password@localhost:3306/database

Auto-generated admin panel for Oxyde ORM with zero boilerplate.

  • Automatic CRUD, search, filters, export
  • FastAPI, Litestar, Sanic, Quart, Falcon
  • Theming, authentication, bulk operations

GitHub →

Full documentation: https://oxyde.fatalyst.dev/

If you have suggestions or find a bug, please open an issue or create a pull request on GitHub.

This project is licensed under the terms of the MIT license.