Now I'll grant you that this may not personally bug you that much. It bugs me quite a bit though.
Now I'll grant you that this may not personally bug you that much. It bugs me quite a bit though.
If you are using a relational database, know sql, and want to eliminate a TON of boilerplate, use an ORM.
I don't know of many ORM's that claim "Use us and you won't have to know SQL". That's just a straw man argument.
If you define breaking down in the terms mentioned by the comment you are replying to, you are playing a semantics game to frame the debate to be: this ORM sucks because I can't use it without knowing sql.
Since most ORMs I've worked with are not really as complicated to learn as you try to make it sound, the trade-off is clear.
EDIT: fixed a typo.
It's just that in software, the argument "If I already know A, so why should I have to learn B" isn't really useful. Given that software is often about pushing down complexity, one of our main tools is building a "B" so that we don't have to do "A".
I know how to write socket code in C, but I'm glad for libraries that don't force me to think about that level--I can pop up a level or two. Examples continue ad infinitum.
On the other hand, I can buy the argument "B isn't really very good at abstracting A; I've tried to use B, and every time I use B, I end up just doing A anyway. So B isn't useful."
But with ORMs, my experience isn't so black-and-white. I find them very useful a lot of the time. When I run into problems, I can switch to doing SQL directly. That's an okay tradeoff for me. I can certainly understand if others don't find that tradeoff as useful.
My point was more B doesn't in my experience abstract A well enough to justify its use in anything other than toy or really simple apps that won't live very long or won't have much maintenance. I don't mind an upfront cost if it means I won't be pulling my hair out at 2am trying to make some database call take less then 10 minutes to complete. (Exaggerating there but you get the idea.)
If B doesn't do a great job abstracting A then the time spent learning B feels wasted to me.
(Edit : extrapolate to abstract)
ORM has lots of benefits. but having to learn less is not one of them. Biggest one is that you don't need to write/maintain a separate code base (sql) for CRUD operations. that's BIG benefit even if you get to use it on 40% of your database interactions. Something as stupid as not worrying about creating the right data conversions and logical types to store data in, will avoid a ton of bugs from intermediate programmers.
No one is forcing you to do anything, you can write your own database access layer if you like. Often developers who do this end up using parts of their code across different projects, basically they write their own ORM.
Or you can use a pre-built ORM, as far as I am concerned for me this is the saner choice. I really doubt I could write something on my lonesome that is as secure, performant and has the features of ActiveRecord in a non trivial amount of time.
But the important part is that whichever path you go down, if your project is growing, complex or needs to scale, you need to know your stack. You need to be able to modify or reconfigure each part. You need to understand at a high level what each part of the stack does, and be able to learn exactly what it does at a low level quickly should the need arise.
Sometimes, this one place is actual a MySQL proxy. Check out ScaleDB, which they just launched - it looks promising.
But other times, it will be in your own app. That is the ORM :) But in that case I wonder how often you really need relational data stores.
You will actually arrive at some sort of ORM if you start abstracting your CRUD operations into ONE PLACE. Basically ORM is the product of DRY.
and it's not a bottleneck? it's shared nothing?
I find ORMs useful for simple CRUD but that's so little of what I do that I mostly don't bother adding a huge framework to my code just to do some CRUD.
A set oriented DB API that cuts down on boilerplate is the way to go in my view. And that is simple enough to create on a weekend.
This works out very nicely for things like web applications where the currently-logged-in-user can only manipulate his own data. You can write your model so that it takes the current user and restricts all data to his rows so that your application doesn't even see data that the user is not allowed to see. It's really quite wonderful and something that raw SQL queries simply don't provide enough abstraction to handle flexibly.
Ultimately, people dislike ORMs for the same reason they dislike things like CoffeeScript. They're not mentally comfortable delegating code generation to a computer program -- that's their job. And so, they will complain whenever they are looking at code that's not exactly what the lower level of the system will see. But in general, that's due to inexperience rather than actual dislike.
The point of working with sets of tuples is that you can apply any set operation to a set of tuples and what you get is a set of tuples. You can use selection, projection or union and you still get a set of tuples. The recursive nature of this principle makes it so powerful and simple. Kind of like Lisp.
ORMs introduce a conceptual barrier between objects defined by domain classes created at design time and generic containers used to hold the result of projections and aggregate functions. If you join over two classes and project over some of their attributes you lose all the properties of the original classes, including any attribute accessor methods. Same thing with aggregate functions and grouping.
Even if the result of a query involving projections or aggregate functions happens to have the exact same attributes as another existing class, you don't get objects of that class and hence none of its methods. The tuples don't compare equal to objects of that class either because they don't share their type.
Different ORMs have various features to partially paper over these issues. I don't want to get caught up in a debate about what ORMs can or cannot do because powerful ORMs like hibernate can do almost anything and everything is optional.
The point is that they discourage me from working in a set oriented fashion because they make it hugely more complex than it needs to be. They create a conceptual mess and then they want me to learn a lot of tuning techniques to fix what is broken as a result of that mess. It makes no sense to me.
But what ORMs encourage you to do is to load a bunch of objects and then use procedural code to do the real thing.
I fully understand that not all types of algorithms and datastructures lend themselves to set oriented thinking. I work mostly with those nowadays. But for those cases it makes no sense to use RDBMS at all.
But what ORMs encourage you to do is to load a bunch of
objects and then use procedural code to do the real thing.
The exact same thing happens when you directly express the query in SQL. You load a bunch of objects and post-process them, to do what SQL can't do. Unless you count the various languages you can use in stored procedures in RDBMS's, but those aren't set-oriented SQL either.My rule of thumb is pretty simple. I use whatever takes fewer and/or simpler lines of code unless it's a lot slower.
The raging scalability debate is a different matter. I'm sure if you're Google there are good reasons to write more lines of code in order to scale better. I'm not Google so I can prioritize productivity over scalability.
Same thing with aggregate functions and grouping.
Why do you expect the resulting object of an aggregate over source objects to have the same kinds of methods? That makes no sense at all. What should the 'name' of a record return when you've aggregated over the salary of many employees? That makes no sense in the original relational algebra, whether expressed in SQL or ORM, either. Aggregating is not a set operation and there part of the false dichotomy comes in: SQL isn't quite as pure and easy to understand as ORM opponents would have you believe.The goal of a query is not to process sets of objects. The goal is to answer a question. The ORM gives you two choices. Either limit yourself to answers that can be expressed as objects of existing classes or get something that is fundamentally different from all other domain objects - a generic tuple of values.
You lose the homogenous, recursive transformation capability that the relational model provides.
In terms of simplicity, I suggest you take a few queries involving joins, group by, having and aggregates and translate them to procedural code. I've done that a lot. It's very eye opening. Functional languages using homogenous data structures like lists or generalized sequences can be similarily productive for data that fits into memory. That is a more and more viable alternative to SQL in my view, but OO systsms and querying/transformation just clash badly.
This is not a good comparison. With ORM, you started with Python/Java/C#/etc + SQL, and ended with Python/Java/C#/etc + SQL (a lot less). There is nothing new added.
With CoffeeScript, you started with JavaScript, and ended with JavaScript + a perlish language.