Can I draw your attention to Sebastian Vetter's investigation of the
relative scalability of different model polymorphism approaches :
https://github.com/elbaschid/talks/tree/master/2013-12-12_MelbDjango_MTI.Performance

Basically, the "select_related then resolve" approach [used in
django-model-utils InheritanceManager] doesn't scale nearly as well as
django-polymorphic's more pre-fetch-related "1+N queries" approach.

--
Curtis


On 7 June 2014 01:00, Luis Masuelli <luisfmasue...@gmail.com> wrote:

> Don't know if it's a big patch at all. A polymorphic call could be like
> this:
>
> 1. Check if the class is polymorphic by itself or by inheritance:
>
> Traverse the inheritance D-Graph (we have to remember it's not a tree
> anymore) starting from the current class - It would stop on (and not count)
> models.Model (abstract=True and proxy models are also not counted). It
> should stop on the first parent having a Meta definition as I exposed
> before.
> Having multiple (concrete) ancestors defining a Meta like that, would
> raise an exception.
> Defining such Meta while an ancestor already defined it, would raise the
> same exception.
> Not finding such Meta in the dgraph would have no effect, and the entire
> process would be ignored (i.e. a norma query could be executed over the
> current model). It could alternatively throw an exception or leave it as a
> settings option (CONTENTTYPE_POLYMORPHIC_EXCEPTION = True #you get the idea)
>
> 2. If the Meta was found, the polymorphic query could be done. Traverse
> the models down from the initial model class (i.e. the one from which the
> PQ was done on) enumerating concrete and nonproxy models. Basing in your
> idea, a narrow=(Model1, Model2, ...) argument could be specified to only
> include those models in the list, ignoring the rest (and stopping when all
> those model classes were iterated and found). As complement, an
> exclude=(Model1, Model2) could be alternatively specified to skip those
> classes (as skipping proxy and abstract classes in the enumeration).
>
> 3. Perform a select_related or prefetch_related query with the enumerated
> classes. This would do a join or prefetch perhaps only on the classes of
> interest (narrow=/exclude=) instead of doing the biggest possible join.
>
> An alternative could be that to define a polymorphic model, the parent
> model could be a brand new contenttypes.models.PolymorphicModel (itself
> being abstract=True) and the nearest concrete ancestors must implement such
> Meta attributes (or an exception should be throw). Perhaps this (abstract)
> model could have a metaclass defining a new Manager for 'objects' attribute
> which could generate a queryset implementing this polymorphic() method.
>
> Such model could have the widely-mentioned get_real_instance (as in
> django-polymorphic) or narrow() as mentioned in the post. The
> implementation could vary: it starts by getting the current object's
> contenttype from the discriminator and get the model class for it. if
> narrow-style is implemented, issubclass() could be called to determine
> whether the object belongs to any of those classes and return the real
> instance if so (it could avoid loading a non-specified class lazily).
> implementing get_real_instance class could load lazily the class if was not
> specified.
>
> As I see, an implementation like I described (which is not new at all)
> could let you leverage the polymorphism level and let you suffer the
> tradeoffs you choose.
>
> Remember that, with this (rant-styled, but improved from reading the post
> you pointed me to) proposal, anyone could choose to use the polymorphism in
> the queries or not, by calling explicitly such method on the query. Not
> using it would behave as normal queries.
>
>
>
> El jueves, 5 de junio de 2014 20:03:14 UTC-5, Russell Keith-Magee escribió:
>
>>
>> On Fri, Jun 6, 2014 at 6:49 AM, Luis Masuelli <luisfm...@gmail.com>
>> wrote:
>>
>>> What about integrating polymorphic features in the ORM? It's like having
>>> the features of django-polymorphic but in the core.
>>>
>>> The polymorphism could be acheved by:
>>>     1. Having contenttypes installed (this is a common pattern).
>>>     2. Specifying a root (first ancestor) model class like:
>>>
>>>     class MyParentModel(models.Model):
>>>         ...
>>>
>>>         class Meta:
>>>             polymorphic = True
>>>             discriminant = "somefield" #it could default to
>>> 'content_type' if not specified. This field could be created.
>>>
>>> To achieve the polymorphism a query could be like:
>>>
>>>     objects = MyParentModel.objects.filter(foo=bar,baz=clorch,...).
>>> polymorphic().more().calls().ifneeded()
>>>
>>> Such method could complain if the contenttypes application is not
>>> installed; it could be based on many select_related() arguments (which are
>>> collected by tree-traversing the hierarchy, perhaps ignoring proxies).
>>> Alternatively, this could be an util in the contenttypes app instead of
>>> the core apps:
>>>
>>>     objects = contenttypes.utils.polymorphic(MyParentModel.
>>> objects.filter(foo=bar,baz=clorch,...)).more().calls().ifneeded()
>>>
>>> Sorry if this was posted before, but it's my first time here and I
>>> always asked why does Django not have this feature in the core.
>>>
>>
>> If you set your time machine to go back 6 years, you'll find the original
>> discussions about model inheritance (implemented by Malcolm Tredinnick, and
>> I did a whole bunch of design/implementation review):
>>
>> https://groups.google.com/forum/#!topic/django-developers/fUCtNz6_qRI
>>
>> In those discussions, we discussed the idea of introducing a CORBA-style
>> narrow() function (which is what you're talking about here) due to the need
>> to add and maintain extra columns, which aren't required for many
>> applications.
>>
>> That said - the decision was at least partially in the interests of
>> landing *something*. We've had 6 years to digest that design, and a bunch
>> of internal API cleanups in the process. Personally, I'm not fundamentally
>> opposed to revisiting this issue - I've had a bunch of places where a
>> narrow() call would have been useful. However, I *would* want it to be an
>> opt-in feature of the model API.
>>
>> But I'd also warn - this isn't a small undertaking. This is going to be a
>> big patch, and you're going to need a champion on the core team if you want
>> to make serious progress in getting this into core.
>>
>> Yours,
>> Russ Magee %-)
>>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/2287ac72-c541-44ec-a268-f49aec03cb64%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/2287ac72-c541-44ec-a268-f49aec03cb64%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAG_XiSAwHYVfG8NWAztsp_B3kw-j39OSLXz%3Dn0bZAsiFUvd9rw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to