Re: Why not Single Table Inheritance?
Am 26.05.2014 00:50, schrieb Craig de Stigter: If you ignore STI, I think it is quite straightforward to solve this with a parent model class which adds a type field, and manager methods to add the select_related calls and "interpret" the type field properly; so I don't see an immediate need for inclusion in core. Well, you don't need select_related calls at all, if you're actually storing things in one table like "single-table inheritance" implies. I too was surprised to find Django doesn't do this, and was unable to find a good third-party app that does it. So I wrote my own: https://github.com/craigds/django-typed-models/ It works well and we have been using it in production for a couple years. ... Thank you very much for your answer. I guess a lot of developers don't want to hear the next lines: I think it is a "not invented here" syndrome: Ruby on Rails did it before. That's a reason to do it different. But I can live with an external library like django-typed-models. It does not need to be in django core. There is a second fear: Some years ago, when I was new to database layout design I tried to avoid to create new tables. And I guess a lot of other did it like this, too. If you could use some tricky algorithm to avoid a database table, I choose to code, not to use a new table. Time has passed and I learned: Structure is more important, code can be replaced. If I can write less code with a good database layout now, I prefer less code. Django ORM and south handles new tables perfect. New tables is an expansion in one dimension, the other dimension is: new columns. That's what STI does: it creates a lot of new columns. When I first read how STI works, I had the same old fear: New columns that is outside my current comfort zone. I want to use STI the next time I need model inheritance. Regards, Thomas -- Thomas Güttler http://thomas-guettler.de/ -- 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/539170D7.8090509%40tbz-pariv.de. For more options, visit https://groups.google.com/d/optout.
Re: Why not Single Table Inheritance?
On Fri, Jun 6, 2014 at 3:42 PM, Thomas Güttler wrote: > > > Am 26.05.2014 00:50, schrieb Craig de Stigter: > > If you ignore STI, I think it is quite straightforward to solve this with >>> a >>> >> parent model class which adds a type field, and manager methods to add the >> select_related calls and "interpret" the type field properly; so I don't >> see an >> immediate need for inclusion in core. >> >> Well, you don't need select_related calls at all, if you're actually >> storing things in one table like "single-table >> inheritance" implies. >> >> I too was surprised to find Django doesn't do this, and was unable to >> find a good third-party app that does it. >> >> So I wrote my own: https://github.com/craigds/django-typed-models/ >> >> It works well and we have been using it in production for a couple years. >> > > ... > > Thank you very much for your answer. > > I guess a lot of developers don't want to hear the next lines: > > I think it is a "not invented here" syndrome: Ruby on Rails did it before. > That's > a reason to do it different. > Poppycock. Allow me to assure you that "What Rails Did" didn't even rate a sideways mention during the design discussions for model inheritance. You can verify this yourself with a bit of a search of the django-dev archives. What *did* factor into the decision - the fact that, in the general case, STI means you have to make almost all the fields in your model NULLable. You lose any semblance of having an actual database schema, and end up writing a whole lot of code to re-implement the features of a database schema instead of using the well tested, robust implementation that the database provides. When Django's model inheritance features were added - over six years ago - we made the decision to implement a solution that made the best usage of database features, not to try and turn a database into an overweight key-value store. 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/CAJxq849xL-TJnr4BMmYJ9%2B_OWNh--pJswS0YJp-X-V%3D-hv2_LQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: Integrating polymorphic queries in the framework
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 > 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 o
LOCALE_PATHS should have a check to make sure it's a list/tuple
I'm playing around with 1.7b4 and I was trying to track down why my app was not auto-reloading when files were changed using the dev server. Turns out, it was an improperly configured LOCALE_PATHS setting. My LOCALE_PATHS was configured like this: LOCALE_PATHS = ( '/path/to/locale' ) At first glance, it looks okay. But it's actually a string and not a tuple since it does not have a comma. This causes a problem in the autoloader, here: https://github.com/django/django/blob/608e6eb2959c6e56e5c702ca0d15fa0e6c2eef16/django/utils/autoreload.py#L98 This would be fine, but since LOCALE_PATHS is a string, calling basedirs.extend(LOCALE_PATHS) actually causes every character in the string to get appended to basedirs. Then it walks through the tree and tries to find .mo files. And since there are 3 slashes in the string, the autoloader attempts to search the root drive 3 times. Bottom line is that having LOCALE_PATHS set to a string with slashes causes autoreloading to essentially take *forever*. Maybe adding a warning/validation to ensure LOCALE_PATHS is a list/tuple would be a good idea? -- 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/c6c18d71-5da5-4aaf-83e9-db3b2d86e430%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: LOCALE_PATHS should have a check to make sure it's a list/tuple
Sure, patches welcome. `django.conf.__init__` already has some "tuple_settings" logic which is looks like would probably work for this. On Friday, June 6, 2014 11:51:30 AM UTC-4, Tim Shaffer wrote: > > I'm playing around with 1.7b4 and I was trying to track down why my app > was not auto-reloading when files were changed using the dev server. > > Turns out, it was an improperly configured LOCALE_PATHS setting. > > My LOCALE_PATHS was configured like this: > > LOCALE_PATHS = ( > '/path/to/locale' > ) > > At first glance, it looks okay. But it's actually a string and not a tuple > since it does not have a comma. > > This causes a problem in the autoloader, here: > > > https://github.com/django/django/blob/608e6eb2959c6e56e5c702ca0d15fa0e6c2eef16/django/utils/autoreload.py#L98 > > This would be fine, but since LOCALE_PATHS is a string, calling > basedirs.extend(LOCALE_PATHS) actually causes every character in the string > to get appended to basedirs. Then it walks through the tree and tries to > find .mo files. And since there are 3 slashes in the string, the autoloader > attempts to search the root drive 3 times. > > Bottom line is that having LOCALE_PATHS set to a string with slashes > causes autoreloading to essentially take *forever*. > > Maybe adding a warning/validation to ensure LOCALE_PATHS is a list/tuple > would be a good idea? > -- 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/657a7af7-033b-4578-a843-baac56f24a5e%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [RFC] Python 3 and MySQL
While we're on the topic, I'd like to propose (also?) supporting the pure-python, MySQLdb-compatible pymysql, which INADA Naoki (methane) has also put a lot of work into. pymysql is pure-python, so it's really easy to get up-and running on Mac OS X and in other environments, because you don't need the mysql header files around. Just pip install pymysql, and you're good to go. https://code.djangoproject.com/ticket/22391 Tim says on the ticket: "One question I have is how we are going to ensure that it doesn't break if we merge it to core. Do we need another MySQL build to the Jenkins matrix?" -- 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/260d5b5e-47e3-4432-848f-b3fe58db1a7a%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [GSOC] Weekly update
Hi All, Based on the work done last week, this week I have worked on the following: *1) Covered the current _meta implementation of unittests* The current Options is not covered by unit tests at all, I have created the model_options test module containing one or more unit tests for each endpoint and usage. Each endpoint is tested with many different models and fields (data, m2m, related objects, related m2m, virtual, ..). Each unit test asserts equality in field naming and field type. Endpoints that return the model are also tested for equality. This branch is found here: https://github.com/PirosB3/django/tree/soc2014_meta_unittests *2) Pulled in tests from soc2014_meta_unittests and tested the new implementation* The previous branch that I developed on contains the new API implementation, I have pulled in the tests from soc2014_meta_unittests and I have switched the old API calls to the new API calls (with a few adjustments). I have successfully made all tests pass even though I have found some design issues that need to be addressed in my next update call. This branch is found here: https://github.com/PirosB3/django/tree/soc2014_meta_refactor *3) Created a new branch that maps the old implementation with the new* Today I started putting my new API in "production". This is obviously nowhere near a finalised version but it helps me spot some edge cases that are not in the unit-tests. Each issue found has been converted into a standalone unit-test and has been proved to fail. Unfortunately, this made me realise of other design issues related to the new return type of get_fields -> (field_name, field), A decision will be taken on monday. This branch is found here: https://github.com/PirosB3/django/tree/soc2014_meta_refactor_implementation as is for personal use only For any questions, let me know! Dan On Sunday, June 1, 2014 6:10:53 PM UTC+2, Daniel Pyrathon wrote: > > Hi All, > > An update on my side, some interesting work has happened this week: me and > Russell have decided to start on the implementation early in order to > understand better the internals of Options. Currently I am working on the > following: > > *Providing one single function: get_fields(types, opts, **kwargs)* > Previously we had identified a number of functions that contained similar > data but had a different return type. We are going to provide one function > that takes a set of field types + options and returns the same output > everywhere: ((field_name, field), ...). This has the benefit of simplicity > and is more maintainable than the previous approach. > > TYPES = DATA, M2M, FK, RELATED_OBJECT, RELATED_M2M > OPTS = NONE, LOCAL_ONLY, CONCRETE, INCLUDE_HIDDEN, INCLUDE_PROXY, VIRTUAL > > *Providing two functions for retrieving details of a specific field* > As specified in my previous document, in many parts of the code we just > want to retrieve a field object by name, other times we have a field but > need other metadata such as: owner (model_class), direct (bool), m2m > (bool). We will provide two functions: > > get_field(field_name) -> field_instance > > get_field_details(field_instance) -> direct, m2m, (still to be defined) > > While we still have not entirely defined what *get_field_details *will > return, this will be done soon. > > > *Building a test suite for the existing API* > The new API development will be driven by a test suite that will compare > the current (legacy) API with the new implementation. While return types > will be different, we are asserting that all the correct fields and > metadata are returned. Building a test suite means we can start > implementing before a final API spec is finalised. It also means we can > iterate faster and, from my perspective, I also understand a lot more of > the current implementation. We are testing each combination of fields and > options together. > > My current implementation is visible here: > https://github.com/PirosB3/django/compare/soc2014_meta_refactor > > For any questions or suggestions, let me know. > > Daniel Pyrathon > > > On Monday, May 26, 2014 1:28:31 AM UTC+2, Daniel Pyrathon wrote: >> >> Hi All, >> >> Just to make you know, I have put up the current _meta API documentation >> here: >> http://162.219.6.191:8000/ref/models/meta.html?highlight=_meta >> As always, feel free to ask questions. >> >> Daniel >> >> On Monday, May 26, 2014 1:26:27 AM UTC+2, Daniel Pyrathon wrote: >>> >>> Hi Josh, >>> >>> The meta API specified in the docs ( >>> https://github.com/PirosB3/django/blob/meta_documentation/docs/ref/models/meta.txt) >>> >>> is the current API. I have documented this in order to understand more of >>> the current implementation and it will be good to show a comparison when a >>> new meta API will be approved. >>> >>> My current proposal ( >>> https://gist.github.com/PirosB3/371704ed40ed093d5a82) and it will be >>> discussed tomorrow with Russell. I will post as soon as I have updates. >>> >>> Daniel Pyr
Re: Why not Single Table Inheritance?
Let me expand on Russell's expletives: On Friday 06 June 2014 09:42:15 Thomas Güttler wrote: > > I guess a lot of developers don't want to hear the next lines: > > I think it is a "not invented here" syndrome: Ruby on Rails did it before. > That's a reason to do it different. > This does deserve calling out, because... > > If I can write less code with a good database layout now, I prefer less > code. Django ORM and south handles new tables perfect. > > New tables is an expansion in one dimension, the other dimension is: new > columns. > > That's what STI does No. If you're considering STI, then the "dimensions" are not orthogonal: STI is an attempt to use added columns _instead_ of added tables. It is, as has already been noted on this thread (by myself as well as others), a form of denormalization -- which means you may get some performance benefits out of it, but you are certain to lose important correctness guarantees. So, asking for STI in the name of better database design is a little inconsistent; doing this while casting doubt on the honesty of other developers -- well, Russell gave a very succinct description of that. Shai. -- 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/2746566.8l84GYph17%40deblack. For more options, visit https://groups.google.com/d/optout.
Re: Why not Single Table Inheritance?
On 6 juin 2014, at 09:42, Thomas Güttler wrote: > I think it is a "not invented here" syndrome: Ruby on Rails did it before. > That's > a reason to do it different. The reason is more simple. Rails was designed around MySQL, a database with a rather casual relationship to data integrity. It will happily truncate data or save invalid values in the name of performance. In the same spirit STI trades data integrity for speed. It avoids joins, which can be very slow on MySQL, but also prevents the database from enforcing constraints. Django was designed around PostgreSQL, a database that cares about its data. That explains many differences in the design of the Rails and Django ORMs. -- Aymeric. -- 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/E238DFA5-8938-4DBD-8E78-0D0B477ACA88%40polytechnique.org. For more options, visit https://groups.google.com/d/optout.
Schema tests and test_foreign_key_index_long_names_regression
Hi, I'm trying to figured out how the test_foreign_key_index_long_names_regression method works. For my (using firebird backend) this test fails with: AssertionError: u'author_foreign_key_with_rea7ef8' not found in {u'ID': {'unique': False, 'primary_key': True}} I see that It's using get_indexes to check if a foreign key field exist as index, but get_indexes returns a different information What am I doing wrong here or am I misinterpreting something wrong? --- Maxi -- 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/b3fbb833-d48d-4687-8e45-28b9bfb5fbb7%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Integrating polymorphic queries in the framework
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 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 >> 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.
Re: Integrating polymorphic queries in the framework
Hosted version of the talk: http://www.roadside-developer.com/talks/2013-12-12_MelbDjango_MTI.Performance/#/ [Thanks, Brenton!] -- Curtis On 7 June 2014 11:52, Curtis Maloney wrote: > 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 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 >>> 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 applica