Well, one thing that's important to do whenever we have a discussion like this is to clearly distinguish between object relational mappers ("ORM") and database abstraction layers. An ORM is a kind of database abstraction layer, but not all database abstraction layers are ORMs. One good tool to study to grasp this is Python's popular SQLAlchemy library, which bills itself as a "SQL toolkit and Object Relational Mapper" (my boldface), with the idea that these are different things. As they put it in their key features page:
No ORM Required
SQLAlchemy consists of two distinct components, known as the Core and the ORM. The Core is itself a fully featured SQL abstraction toolkit, providing a smooth layer of abstraction over a wide variety of DBAPI implementations and behaviors, as well as a SQL Expression Language which allows expression of the SQL language via generative Python expressions. A schema representation system that can both emit DDL statements as well as introspect existing schemas, and a type system that allows any mapping of Python types to database types, rounds out the system. The Object Relational Mapper is then an optional package which builds upon the Core.
The front page describes the ORM like this:
SQLAlchemy is most famous for its object-relational mapper (ORM), an optional component that provides the data mapper pattern, where classes can be mapped to the database in open ended, multiple ways - allowing the object model and database schema to develop in a cleanly decoupled way from the beginning.
The key idea of an ORM is to try and bridge the famous object-relational impedance mismatch. This means defining relationships between user-defined classes to tables in a database schema and providing automatic "save" and "load" operations for your application's classes.
In contrast, non-ORM database abstraction layers tend to be more committed to the relational data model and to SQL, and not at all to object-orientation. So instead of featuring "mappings" between tables and classes and hiding the database schema from the programmer, they tend to expose the database to the programmer but with better APIs and abstractions. For example, SQL query builders allow you to generate complex SQL queries programmatically, without string manipulation, like this (an example from the jOOQ library for Java):
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
.where(BOOK.PUBLISHED_IN.equal(1948))
.fetch();
Now, the Play framework doesn't seem to be 100% in league with what I just described, but their argument seems to be in this general space: work with the relational model directly instead of translating it to classes and back from them.
The jOOQ library is worth studying as a counterpoint to ORMs. They also have some relevant blog entries that are worth a read: