It helps build queries programmatically but doesn't abstract / get too much in your way.
On the "mapping" side, the resultset is just a map.
This is where languages that expose data-first shines
141–150 of 300 posts
It helps build queries programmatically but doesn't abstract / get too much in your way.
On the "mapping" side, the resultset is just a map.
This is where languages that expose data-first shines
I've come to a couple conclusions, over the years. First, when you get down to it, the most-valued feature of ORMs is not the "writing queries in some language other than SQL" feature, it's the "not having to write a mess of mapping code" feature. Second, the biggest drawbacks to ORMs all derive from the "writing queries in some language other than SQL" feature. Fortunately, there are tools out there that solve the "…
Possibly still hibernate for the really advanced crazy stuff, too, though this is more doubtful. I've had pretty good success in the past with Hibernate Geospatial and full text search, for example.
In between those two extremes, just use SQL. It can still be mapped pretty easily with Hibernate and isn't practically harder than SQL would be without Hibernate.
I currently work on a project that is based on Django ORM. Before this, I almost exclusively hand-wrote all SQL. I think you can quickly outgrow the limits of ORM... at least Django's. Whether it's needlessly fighting with ORM to get joins correct, ORM deciding it's going to loop through n records instead of joining on DB server, simply doing complex aggregates that ORM won't support, or doing DB-specific stuff. Post…
Learning it well is important though, and inspecting the SQL that was generated for your test cases after you've implemented a feature is also important.
It can do multiple joins with same table when needed, it can do filtered prefetch, it can do subqueries, it can do exists(), it can do group by, it lets you use SQL functions Django doesn't know about out of the box, etc.
But I think the documentation is not intuitive, and in the complex cases the ORM code looks complicated and I think I prefer writing SQL in that case because there is greater chance that the next developer will know SQL than that of them knowing advanced Django ORM features. Also, more chance of getting stack-overflow help for SQL.
Most of the stuff I said still sticks for me (after reading article, and after using ORM this time).
I haven't programmed much golang. But with Python + Django I can use `./manage.py shell_plus` and can drop immediately into a shell with history, readline support, syntax highlighting, and tab completion, with all model objects in local scope.
I can then do lookups and annotations (Yes, they're expensive, not for production, but save lots of time during the day in a pinch):
Lookup:
Library.objects.filter(books__author__name='Book author')
Annotation: Author.objects.annotate(total_books=Count('books')).filter(total_books__gt=5)
When the data model of a project gets bigger, writing queries by hand gets harder to think about. Perhaps its due to my own overreliance on ORM's: but I can't fathom how I'd manage without them. Because in practice the data models are far more complex than above, and it'd take a lot of time (not to mention mental energy that could be put to use elsewhere)Also, there are ways around performance problems: For one, it may entail rejecting features offered by the ORM. Such as django's content types, multi-table inheritance to instead use abstract inheritance (basically just reusing common fields) and even plain one-to-one relations. They're just too complicated and slow at scale.
Same goes for extending the ORM with stuff like django-polymorphic (and django-model-utils). I've gotten nice performance out of django-polymorphic (and cleaner code), but it's hiding a ton of metaprogramming, there's still a penalty "upcasting" naive models, and they're very burdensome to maintain if APIs fall out of date.
Next is trimming down queries with prefetching, only(), and doing direct ID lookups. This prevents multiple queries from piling up by doing the join ahead of time, only getting fields asked for, and doing the fastest lookup for objects after a more expensive "filtering" query has ran.
Here's an example of the query earlier, with .only():
Author.objects.annotate(total_books=Count('books')).filter(total_books__gt=5).only('id')
And to print the SQL query out: print(Author.objects.annotate(total_books=Count('books')).filter(total_books__gt=5).only('id').query)
That would then be used in something like: BookSet.objects.filter(book__in=Author.objects.annotate(total_books=Count('books')).filter(total_books__gt=5).values_list('id', flat=True))
And finally, for debugging certain types of query performance, django-debug-toolbar is nice. If its API calls django-silk can "look back" on background requests.The article was fair IMO, but I'd wager ORM's payoff depends on the ecosystem. Software being about tradeoffs: the convenience outweighs the downsides everytime for me. Maybe I'm to be humbled and find I'm not getting the big picture, and it could be just plain learnt-dependence, but it'd be a step back in productivity for me not to have an ORM.
I've come to a couple conclusions, over the years. First, when you get down to it, the most-valued feature of ORMs is not the "writing queries in some language other than SQL" feature, it's the "not having to write a mess of mapping code" feature. Second, the biggest drawbacks to ORMs all derive from the "writing queries in some language other than SQL" feature. Fortunately, there are tools out there that solve the "…
I like the Django ORM. This is likely for two reasons: 1. I only use Django for small use cases where I rarely see any sort of scope creep. There was no real conscious decision about this, just kind of the way it happens. 2. The Django ORM is fairly mature and makes it quite easy to get a small project out the door. I regularly use SQL directly at work and wouldn't want to try to replace any of it with an ORM even on…
In fact, missing the database integration wouldn't even be that large loss. Sometimes I wonder if it isn't even holding the framework back.
I've come to a couple conclusions, over the years. First, when you get down to it, the most-valued feature of ORMs is not the "writing queries in some language other than SQL" feature, it's the "not having to write a mess of mapping code" feature. Second, the biggest drawbacks to ORMs all derive from the "writing queries in some language other than SQL" feature. Fortunately, there are tools out there that solve the "…
+1 to everything but the last bit. In my experience, the best compromise is something like Hibernate (or some other ORM) for the mapping and the really basic queries (find by ID, find by some random field, etc). Possibly still hibernate for the really advanced crazy stuff, too, though this is more doubtful. I've had pretty good success in the past with Hibernate Geospatial and full text search, for example. In betwee…
For the few that actually read the manual, there's strongly typed Criteria queries that have the full power of HQL. Which is basically DB agnostic SQL with a few really advanced features removed. There's also lazy loaded collections, caching, change auditing, HBM2DDL validation, mappers that can transparently encrypt/decrypt, calculated columns (calculated by Java code, not SQL), and automatic versioning. All database agnostic.
And with the right settings, it's blazing fast. Maybe only 30% slower than native SQL.
We use all MetaModel strongly typed Criteria queries and it's given us the Holy Grail. Any table or column type or name we change is a compiler error until all the queries are fixed. This has allowed us to rewrite large parts of the schema with confidence that our queries won't break. The ultimate bane of working in SQL without an ORM
I've wound up writing a low key system in, at the time, Scala, that did something to the effect of:
class Select {
fields: Either[List[String], All]
table: String
wheres: List[Clauses]
orderBy: Option[String]
def render(): String
}
The render() method generated SQL; the Select class allowed a _fairly typed_ input; with some evolution, you can get shared queries quite nicely.This works _reasonably well_. Part of _why_ I went this route is that I tend to use Postgres in a very serious way: it's not just a fancy set of spreadsheets with FK linking: I have indexes, check constraints, enums, pg-specific types, triggers, etc. So being able to directly interact with the database gives you a rich control surface that ORMs tend to exclude you from.
By the way, this was an evolution in concept from a different database oriented system I wrote in Python. Both systems used Postgres rich types, the class/render system was implemented in Scala and was Very Nice.
Just say no to ORM. Apart from the usual problems with impedance mismatch, there's one thing that is rarely talked about: Waste. Most ORMs work like that: You get a request, you start a transaction, you begin instantiating lots of objects because you need those to do anything useful. You then either serialize parts of that object tree into JSON or whatever, or you change a few objects, which then create UPSERT statem…
Earlier quoted context omitted.
Well said. I bitterly hated sqlalchemy because many times I knew perfectly well how to write a query in plain sql but for the life of me I couldn't figure out how to write the same query using the sqlalchemy language.
Doesn't alchemy have an execute method, to which you can pass a raw sql?
Not that a little detail like that would stop someone from complaining about something that they don't put in the effort to learn.