Hacker News new | ask | show | jobs
by santiagobasulto 662 days ago
I think Django's ORM is just AMAZING. And as with every other tool, it has to be used wisely.

First, it let's you get started quickly and prototype. You can write unit tests, make sure everything is working as expected, then count queries and make sure you're being efficient with your SQL engine.

Second, and even more importantly, it's crucial in the definition of the app and the Schema. Thinking in high level "classes and objects" helps with the abstraction and the design of the apps. Even if you then default to raw SQU queries, thinking and building your model with class abstractions is huge.

Finally, there are some "tiny details" (but in my eyes, very important) that everybody oversees:

* Migrations: the way Django has designed migrations is just marvelous. We've migrated tons of data and changed the structure of our DB multiple times without any issues.

* Troubleshooting and "reporting": the ability to fire a quick shell, load a few models in Django's REPL, and do a few `.filters()` is for me key. On top of that, we add a Jupyter server connected to our read replica and we can do all sorts of reporting VERY QUICKLY. Not everybody needs a Data Lake :)

PS: We've ran Django sites accessed by millions of people per month. And we never had an issue with the ORM. Yes, sometimes I have to tell more junior devs that the gymnastics they're doing with `select_related` and `prefetch_related` can be more easily and effectively resolved with a query. But that's it. I'd say less than 1% of all the queries in our codebase have to be migrated to raw SQL.

4 comments

One common pitfall with Django ORM's is that it makes it very easy the use of inheritance in models. But as we know, the "impedance mismatch" between OOP and the Relational model is a problem.

It has happened that a dev in our team was populating an endpoint that used inheritance and when looking at the number of queries we were over 100.

But the solution in those cases is just OUTER JOINs and CASE. Especially since we use Postgres in the backend and it works so well.

So yes, there are some pitfalls, but they're greatly overshadowed by the advantages of the ORM.

You have to use the ORM with a bit of awareness of the query it it generates. Django provides plenty of tools and great documentation for reducing, combining and managing queries. It's not like it's a deep dark corner.

It's like understanding memory allocation if you're writing c. It's just part of the job

We've had serious trouble with migration merges when two people work on different parts of the code, yet in the same module, and they both generate a "migration nr. 6" on their feature branches.
Not at my desk but from memory, this is a something with a clearly documented "solution".

I put that word in quotes because I don't want to imply it's a problem - it's just something you need to know how to handle.

That's the problem I have with Python mentality. Everything is great, you just need to know about the myriad of pitfalls and problems. A good environment makes problems obvious and and allows to communicate decisions clearly.

This is the trap of the local maximum.

> ..with Python mentality

As opposed to what mentality ? I mean any tool I worked with has the same problem.

Not that, this is the problem they're referring to:

> > Everything is great, you just

Part of the python mentality is to pretend difficulties aren't there in order to keep presenting itself as beginner-friendly.

Something in the official docs or more like shared through blogs or stackoverflow ?
It's in the standard docs:

https://docs.djangoproject.com/en/5.1/topics/migrations/#ver...

You just rename one of the two files, and add the dependency. If they touch the same fields, you obviously have to resolve that manually.

Thanks a lot
No problem!
May I ask, what experience do you have with other ORMs?
There is one part in me that says to not destroy your positive mood, there is another part in me that wishes to yell at the pythonistas in general to look outside the Python world.

Too often I come across Python projects that are hyped and when I dive into it I find it rather underwhelming to say it politely. Invariably it turns out that those people don´t know any other language than Python.

I see that as a general problem; Python is the language for beginners this day with an endless amount of tutorials, but it seems lots of those starters don´t get to have a look outside the Python world. I fear this is getting an even bigger problem because AI models are trained on a vast range of Python, not because it is better, but simply because it is the PHP of these days.

I don´t mean to imply that I know you have that "narrow profile".

I agree that the value in Python is for quick prototypes in case you know Python well. Outside of that (at the risk of a language war), I think one does better look into modern .net core or the JVM for a general purpose, high quality and highly efficient language/platform.

On the topic of ORM I think EF Core (.net core) and Doctrine (php) is strictly better.

ORMs are a bad idea in the first place: relations are a great way to organise your data, why would you want to sully that by converting to something object oriented?

> Too often I come across Python projects that are hyped and when I dive into it I find it rather underwhelming to say it politely. Invariably it turns out that those people don´t know any other language than Python.

To give a nice counterexample: Python's hypothesis library is really great, and compares favourably to its Haskell inspiration of QuickCheck.

They’re incredibly convenient. It allows smaller groups of people to accomplish more in a shorter amount of time by providing a standardized interface that does a great job of integrating with their existing environment. When translating database input and output into server-side representations, you have two options: build and maintain the process yourself or use a mature tool designed for that specific purpose in your server-side language. I strongly prefer the latter, as do many others. I find that most people critical of ORMs end up creating their own narrowly focused, weakly tested ORM-like database compatibility layers in their backend. These have caused more problems than ORMs ever have.
> When translating database input and output into server-side representations, [...]

I'm saying that your server side representation could also be done as a relation. No need for object orientation. I don't have a problem with the M part of ORM, but with the O part.

_If_ you are having different representations, than having an automated mapper between representations is good. Agreed, yes.

A more appropriate name for ORMs would be "network data model to SQL mappers". They don't facilitate good OOP and oppose relational thinking and data management.
> ORMs are a bad idea in the first place: relations are a great way to organise your data, why would you want to sully that by converting to something object oriented?

One big why is SQL. It's a horrible language/API but sadly practically all relational databases are SQL.

This is the nail on the head.

I’m really not a fan of ORMs, I don’t think they save any time because to use them in a safe way, you NEED to fully understand the SQL that will be run. There’s no shortcut from this and it’s plainly just an extra step.

I’ve been bitten too many times but one ironic problem is that they’re so damned reliable. 99.999% of the time your use of an ORM will be just fine. It can be hard to argue against sometimes even though that 0.001 time can be an extinction level event for the company.

So if you need to understand the SQL that will be run anyway and ORMs occasionally introduce disastrous behaviour, why persist with them?

Well to start with the obvious, SQL is not panacea, you can still be bitten with non-deterministic behaviour when you hand craft every query in sql (e.g. when was the last time you updated stats on that relation - will the optimizer select an appropriate strategy?).

But a stronger reason is that some harder queries just suck to write correctly in SQL. Maybe you’re working with some kind of tree or graph and need a recursive common table expression: Enjoy! It might be better in most cases to write such a query at a higher level of abstraction (ORM) and take advantage of the more productive testing facilities.

I agree that SQL ain't great.

You can model relations in your language without using SQL. (You could have a mapper from your internal modelling of joins etc to how you talk to your database.)

In eg Haskell that works really well, but other languages are also flexible enough.

So horrible that it’s been the standard for 50+ years.

The relational model is great. Embrace it, because it isn’t going anywhere.

Relational model is good, SQL is not. They are not the same thing.
Short of academic languages like D, nothing faithfully implements the relational model. Some compromises are necessary to make it useful for practical applications, hence SQL.
For pythonistas reading this: JVM and .NET frameworks are better for large projects in the sense that they turn even the simplest projects into large messes of pointless byzantine buggy architecture, which in some circles is a sign of "high quality".

Edit: That said, learning multiple programming languages (paradigms) is a very good idea. A reasonable dose of e.g. Java, .NET or C++ for example is great for understanding how programming languages and software should not be written. Learning modern JavaScript makes it obvious how Python really suffers from weak functional programming support, very bad performance and a horrible packaging system.

> For pythonistas reading this: JVM and .NET frameworks are better for large projects in the sense that they turn even the simplest projects into large messes of pointless byzantine buggy architecture, which in some circles is a sign of "high quality".

You got to back up this claim. The technologies you mentioned are entirely orthogonal to the architecture you are using.

This is not even a counter argument. We are talking ORMs here, not dependency injection frameworks.

The Java equivalent to Django ORM would be Hibernate.

It doesn't strike me that you know what Spring does, nor where its own features end.

The comment I replied to was to general development. And Spring is the most popular Java web framework (that it's called a "dependency injection framework" is kinda telling about the architectural ideology).

I've had the misfortune to use both Spring and Hibernate professionally.

Wow, I didn't think people still thought like this in 2024.

The widespread use of Python is a problem? People should learn java? Okay.

I'll note you don't talk about the usefulness of the projects themselves, only your opinion of what the code "looks like".

How are those better?
Statically typed languages, performance, refactorability, instrospection, debuggability, observability, the list goes on.
job security for one big one
no, i'm not about to go back to .net core