Skip to content

Oxyde ORM

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!

Features

  • 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

Why Oxyde?

Performance

Oxyde's Rust core handles SQL generation and query execution, releasing Python's GIL during database I/O. This enables true parallelism for database operations.

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

Type Safety

Built on Pydantic v2, Oxyde provides full type checking for models and queries. Your IDE understands your database schema.

Familiar API

If you know Django ORM, you know Oxyde. The QuerySet API follows Django conventions:

# Django
User.objects.filter(age__gte=18).exclude(status="banned").order_by("-created_at")

# Oxyde (identical)
await User.objects.filter(age__gte=18).exclude(status="banned").order_by("-created_at").all()

Async Native

No sync wrappers or thread pools. Oxyde is async from the ground up:

from oxyde.db import transaction

async with transaction.atomic():
    user = await User.objects.create(name="Alice")
    await Profile.objects.create(user_id=user.id)

Database Support

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

SQLite < 3.35: Falls back to last_insert_rowid() which may return incorrect IDs with concurrent inserts.

MySQL: No RETURNING clause — uses last_insert_id(). Bulk INSERT returns calculated ID range which may be incorrect with concurrent inserts.

Ecosystem

Oxyde Admin

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

  • Automatic CRUD, search, filters, export
  • FastAPI, Litestar, Sanic, Quart, Falcon
  • Theming, authentication, bulk operations
pip install oxyde-admin

GitHub