finds.dev← search

// the find

ponyorm/pony

★ 3,823 · Python · Apache-2.0 · updated May 2026

Pony Object Relational Mapper

Pony ORM translates Python generator expressions directly into SQL by inspecting the AST at runtime, which gives you a query syntax that actually looks like Python rather than a string DSL. It supports SQLite, MySQL, PostgreSQL, Oracle, and CockroachDB. Aimed at developers who want something more expressive than raw SQL but find SQLAlchemy's query API verbose.

The generator-to-SQL translation is genuinely clever — `select(p for p in Product if p.price < 100)` reads like Python because it is Python, not a string that happens to look like it. The identity map and automatic transaction management via `@db_session` remove a whole class of bugs around stale objects and forgotten commits. Test coverage is extensive — the test directory has 80+ test files covering edge cases like deduplication, frame variables, and symmetric many-to-many relations, which suggests the AST translation is battle-tested. The built-in ER diagram editor at editor.ponyorm.com is a nice prototyping tool that generates working entity definitions.

The AST decompilation trick that makes the query syntax work is inherently fragile — it relies on CPython bytecode internals, which means it can break across Python versions or with alternative interpreters. No async support; `@db_session` is synchronous, so it's a dead end if you're building on asyncio or FastAPI with async handlers. Last substantive activity looks thin for a project this old — 3800 stars but only 256 forks and a changelog that hasn't seen major feature work in years suggests it's in maintenance mode rather than active development. Migration tooling is weak compared to Alembic; schema changes require more manual intervention than you'd expect from a modern ORM.

View on GitHub →

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →