They prevent harnessing the power of SQL by providing seemingly convenient shortcuts. Only later (when it's too late and you already invested heavily in it) it becomes clear that one would have been better off not using an ORM but using SQL directly.
ORMs are painful, I only use solutions which help me reducing the amount of boilerplate code to map data to domain objects (Dapper being a great example in .NET land), but I really prefer writing my queries and seeing them at a glance (however ugly they may look when inlined) without having to actually run the app. Plus, SQL produced by things like Entity Framework is not really readable with all those "extent1", "extent2" and so on.
In addition, ORMs tie you to the lowest common denominator so if you want to take full advantage of, say, jsonb in PostgreSQL you're out of luck.
I mean, in principle they're great, and they will theoretically allow you to switch database engines but, according to my limited experience, that is not such a frequent occurrence.
The thing is, they come with too many hidden costs, and I never bought the "no need to know any SQL" argument to begin with, as I really think a decent command of it is part of the fundamental abilities of a developer.
I don't know if you can take 'full advantage' but with the Django ORM, you get special postgreSQL fields to take advantage of postgres jsonb. There is nothing stopping someone from developing more features specific to other RDBMS either... and if you need to write some queries in SQL, the Django ORM lets you do that easily alongside more traditional ORM queries.
https://docs.djangoproject.com/en/1.9/topics/db/sql/#perform...
https://docs.djangoproject.com/en/1.9/topics/db/sql/#executi...
If you're an application developer you've seen what happens what the code dissolves to if developers are rolling their own queries all over the place and doing manual model to object mapping. ORMs have appeal in environments they provide tooling on top and where developers are expected to know how to use them (Entity Framework, Django admin). In other situations like Clojure I would just use something like yesql.
The "N+1 selects" problem ( http://use-the-index-luke.com/sql/join/nested-loops-join-n1-... -- running for loops against nested selects) is probably the most notorious case of this. When you learn SQL, you pretty much learn from the get go that loops are bad (eg, you avoid cursors, and process things in batch, as much as possible). I think it's a lot less obvious that this also is the case in ORM land, that for loop doesn't instinctively look too dangerous when you first start programming using an ORM. (Because in your regular code, it really wouldn't be.)
Personally, I do quite like micro-ORMs like Dapper. Dapper's great at mapping query results to objects, but still allow you to take advantage of SQL performance.
I'm not really a fan of ORMs - I think it's fundamentally an inferior approach and I think clojure/yesql or (presumably) Dapper like micro ORMs are much better where you treat query results like values instead of objects - but at the same time an enormous ammount of work went in to ORMs and a lot of developers are familiar with them to the point where they can do their job in 90% of the cases - and for that 10% case you have the senior dev or a DBA can step in - this IMO is a big value proposition that shouldn't be ignored.
In addition, your data is usually longer lived than the class structure of application, so making a database design based on the object structure means that you can't change your class structure, because you have several terabytes of data you want to keep, following its structure.
But if you want to query from an ORM to a reasonably normalized database, then with a bit of thought, you can almost certainly dodge many of the traps that an ORM can lead the unwary.
And Django has backdoor for you to use raw SQL.
It is not a bad thing if not being abused.