Show HN: Advanced-Alchemy – A framework agnostic library for SQLAlchemy
github.comHello HN!
Advanced Alchemy is an optimized companion library for SQLAlchemy, designed to supercharge your database models with powerful tooling for migrations, asynchronous support, lifecycle hook and more.
You can find the repository and documentation here:
- GitHub Repository: https://github.com/litestar-org/advanced-alchemy
- Official Documentation : https://docs.advanced-alchemy.litestar.dev/latest/
Advanced-Alchemy extends SQLAlchemy with productivity-enhancing features, while keeping full compatibility with the ecosystem you already know.At its core, Advanced-Alchemy offers:
- Sync and async repositories, featuring common CRUD and highly optimized bulk operations
- Integration with major web frameworks including Litestar, Starlette, FastAPI, Sanic
- Custom-built alembic configuration and CLI with optional framework integration
- Utility base classes with audit columns, primary keys and utility functions
- Built in File Object data type for storing objects:
- Unified interface for various storage backends fsspec and obstore
- Optional lifecycle event hooks integrated with SQLAlchemy's event system to automatically save and delete files as records are inserted, updated, or deleted.
- Optimized JSON types including a custom JSON type for Oracle- Integrated support for UUID6 and UUID7 using uuid-utils
- Integrated support for Nano ID using fastnanoid
- Pre-configured base classes with audit columns UUID or Big Integer primary keys and a sentinel column.
- Synchronous and asynchronous repositories featuring:
- Common CRUD operations for SQLAlchemy models
- Bulk inserts, updates, upserts, and deletes with dialect-specific enhancements
- Integrated counts, pagination, sorting, filtering with LIKE, IN, and dates before and/or after.
- Tested support for multiple database backends including: - SQLite via aiosqlite or sqlite
- Postgres via asyncpg or psycopg3 (async or sync)
- MySQL via asyncmy
- Oracle via oracledb (async or sync) (tested on 18c and 23c)
- Google Spanner via spanner-sqlalchemy
- DuckDB via duckdb_engine
- Microsoft SQL Server via pyodbc or aioodbc
- CockroachDB via sqlalchemy-cockroachdb (async or sync)
The framework is designed to be lightweight yet powerful, with a clean API that makes it easy to integrate into existing projects.You can find a full example using FastAPI there: https://docs.advanced-alchemy.litestar.dev/latest/usage/fram...
There are custom datatypes, a service and repository (including optimized bulk operations), and native integration with Flask, FastAPI, Starlette, Litestar and Sanic.
Feedback and enhancements are always welcomed! We have an active discord community, so if you don't get a response on an issue or would like to chat directly with the dev team, please reach out.
The library: https://github.com/litestar-org/advanced-alchemy
I'm using SQLAlchemy, Alembic, and FastAPI. Either this is for someone much more advanced than me, or it could use some examples showing "This is clunky in SQLAlchemy and easy in Advanced-Alchemy." When you look at SQLModel[1] from FastAPI, which I did adopt, it does a much better job at promising "this will make your life easier".
1. https://sqlmodel.tiangolo.com/
I don't like SQLModel for the simple reason that it muddles boundaries between different parts of the application. I suppose when you have a pure CRUD app it's ok, but anytime you want to handle ORM objects and apply some business logic; you'll want to cleanly separate those from what you send and receive from your API.
Hello, OP there, I have many use cases that fall outside of FastAPI or web apps in general, and this pattern allows me to consolidate that logic in a re-usable way.
We also have SQLSpec[1] (Work in progress) that could maybe a better use case for you with raw SQL
1. https://github.com/litestar-org/sqlspec
FastAPI and it's very opinionated "ecosystem" of "easy to use" and "hipster-esque documented" tools are fast-becoming a horrible one-man show version of Django, and we will all regret going so deep into it using it, one day. Until then, sure we can use it and it mostly makes sense and it mostly works really very well. Hopefully the community matures and moves away from opinionated tooling that forces you into the "one true way".
I use this library in production; it has great tools and features that I couldn't find in Python, that I missed from other frameworks or languages. The only downside is that you have to figure out what is what from the code; the documentation is not good. But once you figure out the details, it's downhill from there. We use this with the Litestar framework; there are things that I hate, but in general, it works out really well. Especially, if you managed to set up your services, repositories correctly, then many things happen magically. Though I suggest anyone who'd like to "taste" these use `msgspec` as a serialisation library. We hit the wall earlier when we wanted to use Pydantic in complex schemas for serialisation, so we went back to msgspec. The downside is that msgspec misses the validation part.
Anyway, I recommend that anyone go beyond the regular SQLAlchemy. I like the syntax `account = await accounts_service.get_one_or_none(*filters, id=account_id)` a lot.
Code examples could be further forward, I clicked around a bit and didn't see any on the initial pages.
This is a nice library and a really big time savings part of the litestar ecosystem. The litestar community has been really great and helpful in my experience so a big thank you to all the guys and gals over there!
I don't think I ever worked with an ORM that turned against me more than SQLAlchemy and that's not because it's badly written, on the contrary.
Nice, love seeing litestar continue improving!
[dead]
[flagged]