4

Recently I had what seems to be a common question for Django regarding model inheritance. I have a bunch of different models that I want to display either individually or as a group. Read as: query the database for everything in it, or just a certain category (model) of items.

Ultimately, I settled on multi-table-inheritance. My models look something like:

class Unit(models.Model):
    etc, etc...

class Child1(Unit):
    etc, etc...

class Child2(Unit):
    etc, etc...

So now I can query units to get everything and individual children to get more specific. It works fine, but I just looked at the SQL generated for a list of all units...it gets pretty ugly!

SELECT "all the fields from all the tables (Unit and Children)" 
FROM "Unit" 
LEFT OUTER JOIN "Child1" ON ("whatever") 
    LEFT OUTER JOIN "Child2" ON ("whatever") 
        LEFT OUTER JOIN "Child3" ON ("whatever") 
            LEFT OUTER JOIN "Child4" ON ("whatever") 
                LEFT OUTER JOIN "Child5" ON ("whatever")

Basically, each child of Unit will require another left outer join when I get an index view of all items.

Assuming I have at most 5 children of Unit and that there will be at most 200 items in the DB, is this a deal-breaker? I can always just cache the index view, yes? Or am I missing another problem with MTI? The book "2 Scoops of Django" is absolutely against using multi-table-inheritance...to the point of saying "don't do it ever". But I feel like it solves my problem, is easily understood, and is almost a necessary evil given how Django handles relations.

Keep what I have or go back to the drawing board?

karthikr
  • 97,368
  • 26
  • 197
  • 188
palooka
  • 71
  • 1
  • 6
  • Could you expand your question? I see that you have a problem, but I cannot suggest a different solution because I don't see the problem, only your solution for it. – Augusto Hack Nov 16 '13 at 20:17

1 Answers1

0

If your problem is loading data that you don't need, you can use the only method to retrieve only the data that you need from the database.

If the problem is somewhat in this shape:

You have one model that always have values in, but it can have a couple of different "profiles" that might or might not be filled in.

I think you are in good shape, I mean, the alternative is to have everything be nullable, which isn't nice, or to use ForeignKeys, which is gonna result in the same sort of query. The only note that I have is that you should use model inheritance only if it makes sense for the entities that you are working with, otherwise you can use a OneToOne field (this is only conceptually because inheritance uses a OneToOne field under the hood)

Augusto Hack
  • 2,032
  • 18
  • 35
  • It's not the amount of fields included in the SQL that bothers me, it's the 5 joins! I'm just wondering how bad this really is from a performance standpoint; if it might be worth it to reconsider how my models are structured. I've heard a lot of "down with multi-table-inheritance" talk (and I suspect this joining shenanigans is one of the key reasons), but I am wondering how big of a deal it _really_ is...and how much of it is just "best practice snobbery" :) – palooka Nov 16 '13 at 20:47
  • What I wanted to say is: If you have only split the models because you wanted to load just part of the data, you could just have one model with all the data and selectively load what you want with `only`, this way there is not a single `join`. – Augusto Hack Nov 16 '13 at 21:03