[Fixed]-Django: mutate queryset to another model on the fly


You might get a better result if you follow the relationship one more step, rather than using in.



I know next to nothing about databases, but there are many warnings in the Django literature about concrete inheritance class B(A) causing database inefficiency because of repeated INNER JOIN operations.

The underlying problem is that relational databases aren’t object-orientated.

If you use Postgres, then Django has native support (from 1.8) for Hstore fields, which are searchable but schema-less collections of keyword-value pairs. I intend to be using one of these in my base class (your A) to eliminate any need for derived classes (your B and C). Instead, I’ll maintain a type field in A (equal to “B” or “C” in your example) and use that and/or careful key presence checking to access subfields of the Hstore field which are “guaranteed” to exist if (say) instance.type==”C” (which constraint isn’t enforced at the DB integrity level).

I also discovered the django-hstore module which existed prior to Django 1.8, and which has even greater functionality. I’ve yet to do anything with it so cannot comment further.

I also found reference to wide tables in the literature, where you simply define a model A with a potentially large number of fields which contain useful data only if the object is of type B, and more yet fields for types C,D,… I don’t have the DB knowledge to assess the cost of lots of blank or null fields attached to every row of a table. Clearly if you have a million sheep records and one pedigree-racehorse record and one stick-insect record, as “subclasses” of Animal in the same wide table, it gets silly.

I’d appreciate feedback on either idea if you have the DB understanding that I lack.

Oh, and for completeness, there’s the django-polymorphic module, but that builds on concrete inheritance with its attendant inefficiencies.

Leave a comment