An opinionated, modern ORM for Python combining the power of SQLAlchemy 2.0 with a clean, symmetrical API for sync and async operations.
Project description
DuoORM
An opinionated ORM with symmetrical sync/async APIs, explicit unit-of-work control, and ready-to-use Alembic scaffolding. DuoORM manages drivers for you: use driverless URLs like postgresql://... or sqlite:///app.db and it wires up the correct sync/async engines under the hood (SQLAlchemy 2.x).
Highlights
- One API for sync and async (add
awaitwhen needed). - Explicit unit of work: single-statement by default; opt into
db.transaction()for shared sessions and cascades. - Driverless URLs; DuoORM injects the right sync/async driver per dialect.
- Import common SQLAlchemy types and helpers directly from
duo_orm(e.g.,String,JSON,PG_ARRAY,text,func). - Built-in Alembic CLI scaffolding and migration commands.
- Tested across PostgreSQL, MySQL, MSSQL, Oracle, and SQLite (coverage matrix).
Install
pip install duo-orm # core + sqlite
# Or pick your dialect
pip install "duo-orm[postgresql]" # psycopg (sync+async)
pip install "duo-orm[mysql]" # pymysql + asyncmy
pip install "duo-orm[mssql]" # pyodbc + aioodbc
pip install "duo-orm[oracle]" # oracledb (sync+async)
pip install "duo-orm[all]" # install everything
SQLite fallback (only if your Python lacks stdlib sqlite3, e.g., minimal Docker/Lambda):
pip install pysqlite3-binary
python - <<'PY'
import sys, pysqlite3
sys.modules["sqlite3"] = pysqlite3
PY
Quickstart
from duo_orm import Database, Mapped, mapped_column, String
db = Database("sqlite:///./app.db") # driverless URL
class User(db.Model):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
# One-shot (single statement/session)
user = User.where(User.name == "Ada").first()
# Transactional work (shared session)
async def create_user():
async with db.transaction():
u = User(name="New")
await u.save()
# When you're done (scripts/CLIs), optionally tear down engines
db.disconnect()
Engine lifecycle helpers
db.connect()eagerly initializes sync/async engines so misconfiguration surfaces early (optional; engines still initialize lazily).db.disconnect()disposes any initialized engines and clears cached factories; use it at the end of scripts/CLIs to release pools explicitly. Context managers (db.transaction(),standalone_session(),sync_standalone_session()) already close sessions on exit.
Documentation
- Full docs & guides: https://duo-orm.readthedocs.io/
- Quickstart: https://duo-orm.readthedocs.io/en/latest/quickstart/
- API reference: https://duo-orm.readthedocs.io/en/latest/reference/
License
MIT
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
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 duo_orm-0.1.2.tar.gz.
File metadata
- Download URL: duo_orm-0.1.2.tar.gz
- Upload date:
- Size: 39.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bcc7a8b4d764f72041f55c0af119c1ca755127fb14c84877704706977036012
|
|
| MD5 |
926a59925278f93229a22b781f052d44
|
|
| BLAKE2b-256 |
891d3f91d51a51e69fdbe44cecb944869aae8cfbdfb8462e3d43b43c329aa5c2
|
File details
Details for the file duo_orm-0.1.2-py3-none-any.whl.
File metadata
- Download URL: duo_orm-0.1.2-py3-none-any.whl
- Upload date:
- Size: 28.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8ce4875e217b765fff302d29b1891d697892c701945fb910ffb5f1c306628a6
|
|
| MD5 |
b0280d24648ef67dcc8952afc264403c
|
|
| BLAKE2b-256 |
a20d599f0669bf44339b37da4af5207652ab16798bb5e97dc1e97e416725f628
|