ORMs are a thing of the past
codemonkeyism.com
codemonkeyism.com
FWIW, I use DBIx::Class.
I also agree that ORMs are a bad fit for many programs. Most of the applications that people are writing don't need a relational database at all, as arbitrary queries wouldn't make much sense. In that case, you might as well use an object database -- then there is no querying and there is no impedance mismatch. The result is an app that runs fast and is fast to implement.
The ORM we use at massify (which is open sourced at http://heavyfuckingmetal.com) I've never run into the issues I've seen everyone bitching about in these gloomy, doomsday posts about ORMs. Our ORM even works seamlessly with NoSQL KV stores, as well as things like Solr/Lucene. All very transparently, all very easily.
For a real sense of the horrors behind the scenes have a look at what actually gets passed to your db engine on the backside of the ORM.
For the 2% of the time when it doesn't, you can always just optimise that specific part of the code...
For a real sense of the horrors behind the scenes have a look at what actually gets generated by the compiler.
http://buzhug.sourceforge.net/ has been really great for my Python work.
ORMs make programming easier, but with anything that makes something easier there are certain things that will be harder, as the author mentions, finding bugs created at the ORM level.
Anyone using ORMs is going to be hindered in some way, if they are very creative and if they are creative, but not adept at doing what it is they will want to do without the ORM, then the application and end user may suffer.
You see, in database you've got tuples and nothing else, and in program, you've got objects and nothing else. You have to convert one to another this way or that way.
Talking about dynamically-typed languages, you can treat data as key-value pairs (where values can be arrays or their own key-value pairs) and thus skip this problem entirely.
But yeah, Hibernate is painful enough to make one want to escape conventional ORMs. What we really need is something like XStream of SQL: i.e. just take the result of query (set of tuples) and populate objects using reflection.
(One of the ways that SQL shows its age is that it isn't very composable, which is a fatal flaw. This can at least be papered over in better languages, though it would be better if the actual DB language wasn't so... 70s.)
This avoids many problems with DSLs: Aggregate SQL functions work again and aren't that special. If you don't actually want a 1-to-1 mapping of rows to objects, you have the opportunity to do something more clever. The downside is that you need to think more about your interaction with the DB and that it takes a fairly mature programmer to avoid getting tightly coupled with the DB, not to mention a language with powerful enough abstractions to let you not be tightly coupled with the DB.
I suspect there's a good replacement library waiting in here. SQLAlchemy in Python has some aspects of this, I think, though the ORM heritage still shines through. It will never be as easy as ORMs promised to be, but it could very well end up being easier than ORMs actually are. Since ORMs have never delivered on their promise, I think we can stop holding things to that entirely-theoretical standard.
Brilliant! My solution to this problem using Propel was to make fake objects that map to views rather than tables. It's worked out splendidly so far.
I'm not sure what performance is going to be like in the long term, but it sure beats the O(n) queries that were written before I got there.
Ocaml has PG'Ocaml for instance:
"PG'OCaml provides an interface to PostgreSQL databases for Ocaml applications. It extends the Ocaml syntax, enabling the embedding of SQL statements inside the Ocaml code, and checking at compile-time the consistency between the programme and the DB."
You still need to work with the concept of the database returning a set of data rather than a single row, but that can be done with a little code as well.
Writing the naive ORM implementation that tries to model a relational schema as a sets of nested objects is doable, but it becomes difficult to get decent performance out of it, since the kinds of queries that map rows to objects are not usually the kinds of queries that are performant in SQL.
And having that, you don't really need ORM, naive or not.
List<MyObject> myobjects = dbUtils.select("SELECT name,age FROM (some complex query ... )", params, MyObject.class)
BeanHandler will automatically fill any property in MyObject with a column of a matching name from the select statement.