For optimizations: my_queryset.explain(verbose=True, analyze=True) is very nice to understand what is going on. If you cannot get it done with django's database abstractions, there is always:
my_queryset.extra() or even my_model.objects.raw(). Where the last one maps the result to the model, for free.
To others responding that ORMs are bad: IMHO saying that raw sql is better than ORMs is short sighted. Many simple things are nice in ORMs. Queries are often simple. Today, in django, complex queries are also nice. For edge cases raw sql can be better.
Extending queries is also super easy with a good ORM, where with raw sql you would have to maintain two almost the same queries.
Just remember to run and inspect queryset.explain().
Additionally, we often have to create ad-hoc queries to answer questions from stakeholder. It's easy enough to just pop up DataGrip and write the query, and copy the tabular results into a doc in Google Sheets for sharing.
I think the best approach is ORM-first, not ORM-only.
Having separate applications with (write) access to the same database is similarly going to end in trouble. Suddenly there are all sorts of problems when the database needs a migration and the applications are expecting different things from the same table. This is not really ORM-related btw.
That said, ActiveRecord is not perfect and sometimes a single handcoded SQL query can deliver a ton of value. Profile carefully.
Is that really true? While I've barely used Rails in anger, and not at all recently, I was under the impression that all the major Ruby ORMs and high-level database libraries (e.g., DataMapper, Sequel) are heavily focussed on Rails usage and usually around AR pain points like working with DBs in Rails that don't fit ARs opinionated patterns.
> Having separate applications with (write) access to the same database is similarly going to end in trouble.
It shouldn't, if the DB is designed for that, which usually means each application sees the DB exclusively through its own set (probably in a distinct schema) of views, and keeps it's filthy little hands off base tables. That's a best practice for multiple application access to an RDBMS that is older than the Web.
However, even in an ideal data model, I don't always agree that multiple applications accessing the application's database is bad. That's a matter of being thoughtful and communicative, instead of just wantonly running "rails g migration" every time you need to implement a feature (that's true of Monorails even). FWIW, we've never had any real issues with multiple applications accessing our single database.
Most of the issues I see is a lack of understanding of things like N+1 queries. I see this mistakes from junior to senior level. ActiveRecord has built in solutions to fix them too. Some developers don't know about them.