alchemiq¶
The data layer for async FastAPI microservices: Django-style models, transactional outbox, caching, and ClickHouse - built on SQLAlchemy 2.0.
alchemiq is a batteries-included data layer built on SQLAlchemy 2.0’s async engine. It ships the infrastructure every async service otherwise rebuilds by hand - Django-style models, repositories, Unit of Work, a transactional outbox, caching, migrations, and health checks - as one coherent, well-tested suite, so you focus on business logic instead of plumbing. It targets Python 3.12+, SQLAlchemy 2.0, Pydantic 2, and PostgreSQL (async only).
Highlights:
Async PostgreSQL and ClickHouse - a single query DSL covers both backends.
Django-flavoured models: declare fields with plain type annotations;
Qobjects,QuerySetchaining,order_by,limit, andoffsetwork exactly as you would expect.Repository+UnitOfWork- full CRUD, bulk operations, cursor/keyset pagination, and aggregations (Count,Sum,Avg,Min,Max) out of the box.Soft-delete, signals (pre/post create/update/delete), and optimistic locking - opt in per model via a
Metaclass.Serialization -
to_dict,to_schema,to_pydanticwith field inclusion/exclusion.Outbox + Relay - atomic event capture in the same transaction, published to RabbitMQ/Kafka/NATS via TaskIQ or FastStream.
FastAPI integration - auto-generated CRUD router, DI-ready repository + UoW providers, Pydantic schema generation, and a
/health/ready·/health/liverouter.FastStream consumer DI - inject sessions, UoW, and repositories into message handlers.
Redis caching - per-repository cache with automatic invalidation on write.
Migrations - Alembic wrapper for PostgreSQL; a custom engine for ClickHouse.
Scaffolding -
alchemiq initgenerates a production-ready layered project skeleton.
30-second example:
import alchemiq
from alchemiq import Model, Repository
from alchemiq.types import PK, Email
class User(Model):
id: PK[int]
name: str
email: Email
alchemiq.configure("postgresql+asyncpg://user:password@localhost/mydb")
await alchemiq.create_all()
users = Repository(User)
user = await users.create(name="Ada Lovelace", email="ada@example.com")
found = await users.get(id=user.id)
print(found.name) # Ada Lovelace
See the Getting started guide for the full walkthrough.
Guide
- Getting started
- Models and field types
- Writing a custom field type
- Native SQLAlchemy columns (escape hatch)
- Relationships
- Queries: Q and QuerySet
- Repository
- Unit of Work
- Soft delete
- Signals and hooks
- Optimistic locking
- Serialization
- FastAPI integration
- Outbox and relay
- Caching
- ClickHouse support
- Migrations
- Health checks
- Project scaffolding (alchemiq init)
- What’s not in v1