I don't disagree with you, ORMs can be a great time-saver for your average CRUD app, where the SQL queries tend to be straightforward SELECT/UPDATE/DELETEs on primary keys, assuming you don't mind the overhead of learning the DSL. But as your querying requirements get more complicated, you either have to:
- Keep the DB queries simple and do the complicated stuff (joining, aggregating, etc) in the business logic, or
- Learn how to express your complicated SQL in the ORM's DSL, or
- Drop into the ORM's "raw" mode and write plain SQL
The first option might be fine for non-performance-sensitive stuff, but otherwise isn't making good use of the database, and the latter two options reveal the SQL behind the curtains, at which point the abstraction of the ORM is more or less totally broken.
[1] Raw SQL: https://github.com/bcspragu/stronk/blob/main/db/sqldb/sqldb....
[2] sqlc: https://github.com/bcspragu/logseq-sync/blob/main/db/sqlite/...