Re: Why not Single Table Inheritance?

2014-06-11 Thread Florian Apolloner


On Wednesday, June 11, 2014 2:16:06 AM UTC+2, Craig de Stigter wrote:
>
> I reserve judgment on whether STI should be included in core. It works 
> fine in a third-party app. Some better support for it in core would be 
> helpful, since currently I'm relying on some unsupported stuff that the 
> core devs could decide to break at any time.
>

We'll happily add hooks to make support easier, patches welcome.

Cheers,
Florian 

-- 
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/77aff80c-2a47-4c01-b59a-5576d9b210fa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-06-10 Thread Craig de Stigter
Late reply I know but I see a lot of FUD in this thread and I want to try 
and clear it up.


> 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.

This is just not true. Well implemented STI does *not* turn your database 
table into a key-value store. You can use the fields of the table just like 
you would normally use them. The *only* abnormal consideration here is 
that, if you *need* for some reason to have a field defined on a child 
class instead of all fields defined on the base model, then such fields 
must be nullable.

In my experience users of django-typed-models will have 90-100% of their 
fields defined on the base class for each abstract type, meaning that only 
0-10% of the fields will have to be nullable. There is no deviation from 
normal use of the ORM, and no hoops to jump through to ensure db 
consistency.

In my own case, I am using django-typed-models with all the fields on the 
base class. In fact, django-typed-models didn't initially allow for fields 
on child models at all, and I still don't use that behaviour. I did merge a 
PR to add the possibility for fields defined on child models, and I can see 
how that would be useful. If you use that functionality you just have to be 
okay with those fields being nullable.


> Django was designed around PostgreSQL, a database that cares about its 
data.

And I wouldn't use MySQL if you paid me. But this is a straw man; if you're 
using STI you *might* be using fields that are nullable but could otherwise 
be non-nullable, but this shouldn't imply that you don't care about your 
data.


I reserve judgment on whether STI should be included in core. It works fine 
in a third-party app. Some better support for it in core would be helpful, 
since currently I'm relying on some unsupported stuff that the core devs 
could decide to break at any time.

But it's a better solution to certain problems than MTI is, and it doesn't 
deserve the bashing that some people seem to give it. Use the right tool 
for the job. If that's STI then use STI :)


Craig de Stigter


On Saturday, 7 June 2014 06:05:29 UTC+12, Aymeric Augustin wrote:
>
> 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/d5114d13-a1d2-4f28-85c6-1771d3896f2e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-06-06 Thread Aymeric Augustin
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.


Re: Why not Single Table Inheritance?

2014-06-06 Thread Shai Berger
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?

2014-06-06 Thread Russell Keith-Magee
On Fri, Jun 6, 2014 at 3:42 PM, Thomas Güttler <h...@tbz-pariv.de> 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: Why not Single Table Inheritance?

2014-06-06 Thread Thomas Güttler



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?

2014-05-25 Thread 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.

It does rely on a few hacks that Django doesn't officially support, like 
proxy models with their own fields, which has unfortunately been broken in 
django 1.7 <https://code.djangoproject.com/ticket/22690>. I'd love to see 
better support for this in Django core.


Regards
Craig de Stigter

On Thursday, 22 May 2014 21:02:48 UTC+12, Anssi Kääriäinen wrote:
>
> On 05/22/2014 11:13 AM, Shai Berger wrote: 
> >> Any thoughts on this idea? 
> >> 
> > Instinctively -- isn't it possible to achieve the same things today by 
> > overriding __new__ ? 
> My understanding is that achieving all the same things isn't possible. 
> The problem is that inside __new__ it is impossible to know if the call 
> to __new__ was made from database loading or from user code. It also 
> seems that it is impossible to alter the args and kwargs passed to 
> __init__(). In addition if one wants for some reason (speed, or not 
> invoking __setattr__) to assign values directly to the __dict__ of the 
> new class, then __new__() doesn't seem to offer any way to do that. 
>
> It is true that STI is likely possible with usage of __new__() as long 
> as you don't want to change the arguments to the __init__ call of the 
> created object. 
>
> As a side note I think direct assignment to __dict__ on model loading 
> would be a better design than the current __init__ call. For example 
> Django needs to do some pretty crazy stuff  in __init__() to support 
> deferred field loading. With direct __dict__ assignment deferred model 
> creation is trivial. Also, loading from the database is a form of 
> deserialization, and when deserializing you want to load the model as it 
> were saved. The way to do this is to avoid __init__, __setattr__ and 
> descriptor __set__ calls. To avoid those the values should be assigned 
> directly to the __dict__ of the object. This is also used by Python's 
> deserialization. Of course, thinking about this is mostly academic. 
> Changing the way model loading from database is done has severe 
> backwards compatibility issues. Even django-core relies on descriptor 
> calls in some case. As an example to_python() method of custom fields is 
> called through a descriptor. 
>
>   - Anssi 
>

-- 
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/ffb11c40-c231-48d5-898a-71684536f55e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-05-22 Thread Anssi Kääriäinen

On 05/22/2014 11:13 AM, Shai Berger wrote:

Any thoughts on this idea?


Instinctively -- isn't it possible to achieve the same things today by
overriding __new__ ?
My understanding is that achieving all the same things isn't possible. 
The problem is that inside __new__ it is impossible to know if the call 
to __new__ was made from database loading or from user code. It also 
seems that it is impossible to alter the args and kwargs passed to 
__init__(). In addition if one wants for some reason (speed, or not 
invoking __setattr__) to assign values directly to the __dict__ of the 
new class, then __new__() doesn't seem to offer any way to do that.


It is true that STI is likely possible with usage of __new__() as long 
as you don't want to change the arguments to the __init__ call of the 
created object.


As a side note I think direct assignment to __dict__ on model loading 
would be a better design than the current __init__ call. For example 
Django needs to do some pretty crazy stuff  in __init__() to support 
deferred field loading. With direct __dict__ assignment deferred model 
creation is trivial. Also, loading from the database is a form of 
deserialization, and when deserializing you want to load the model as it 
were saved. The way to do this is to avoid __init__, __setattr__ and 
descriptor __set__ calls. To avoid those the values should be assigned 
directly to the __dict__ of the object. This is also used by Python's 
deserialization. Of course, thinking about this is mostly academic. 
Changing the way model loading from database is done has severe 
backwards compatibility issues. Even django-core relies on descriptor 
calls in some case. As an example to_python() method of custom fields is 
called through a descriptor.


 - Anssi

--
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/537DBD38.4080604%40thl.fi.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-05-22 Thread Shai Berger
On Thursday 22 May 2014 11:05:24 Anssi Kääriäinen wrote:
> I think it is time to add a new model classmethod from_db() to Django.
> 
> The idea is to allow customization of object initialization when loading
> from database. Instead of calling directly model.__init__ from the queryset
> iterators, Django calls model_cls.from_db(). The default implementation
> calls just model.__init__, but by overriding from_db() it will be possible
> to do interesting things. 

[...]

> 
> Any thoughts on this idea?
> 

Instinctively -- isn't it possible to achieve the same things today by 
overriding __new__ ?

-- 
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/201405221113.53601.shai%40platonix.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-05-22 Thread Anssi Kääriäinen
I think it is time to add a new model classmethod from_db() to Django.

The idea is to allow customization of object initialization when loading 
from database. Instead of calling directly model.__init__ from the queryset 
iterators, Django calls model_cls.from_db(). The default implementation 
calls just model.__init__, but by overriding from_db() it will be possible 
to do interesting things. For example:
  1) It allows for faster loading of models. See 
https://code.djangoproject.com/ticket/19501 for some benchmarks.
  2) Possibility to return polymorphic classes from querysets. For example 
for STI:
def from_db(cls, using, fields, values):
# Assume database has type column, and the class contains a 
_type_map pointing to the wanted class for each different type.
data = dict(zip(fields, values))
model_cls = cls._type_map[data['type'])
new = model_cls(**data)
new._state = ModelState(using, adding=False)
return new

  3) Allow differentiating database loading from initialization in user 
code. For example (pseudo-codeish) automatic update_fields on save():

class AutoTracking(models.Model):
fields...

@classmethod
def from_db(cls, using, fields, values):
new = super().from_db(using, fields, values)
# This step is surprisingly hard to do correctly at the moment!
# Can't use overridden __init__ or signals as they don't know 
if the model is loaded from the
# database or not.
new._old_data = dict(zip(fields, values))
return new

def save(...):
if update_fields is None:
update_fields = set()
for attr_name, v in self._old_data.items():
if getattr(self, attr_name) != v:
update_fields.add(attr_name)
super().save(...)


So, there are several advantages to adding from_db(). The only problem I 
can see with this approach is that the default model initialization code 
path will be around 5%-10% slower due to the extra from_db() call for each 
row. To me that isn't big enough slowdown to worry about. In addition, as 
shown in #19501, usage of from_db() allows for significantly faster model 
loading for special cases.

The patches in #19501 are IMO too complex. The patches try to automatically 
detect when we can skip calling model.__init__. Instead we should just add 
the from_db() hook without any fast-path automation.

Any thoughts on this idea?

 - Anssi

On Friday, May 16, 2014 5:06:18 PM UTC+3, Carl Meyer wrote:
>
> On 05/16/2014 04:46 AM, Shai Berger wrote: 
> > On Monday 12 May 2014 12:27:01 Thomas Güttler wrote: 
> >> Single Table Inheritance is used by ruby-on-rails and SQLAlchemy. 
> >> 
> >> Are there reasons why it is used in django? 
> >> 
> > 
> > Essentially, STI is a form of database denormalization. I think Django 
> should 
> > not encourage this. 
>
> I agree. 
>
> >> I would love to see a polymorphic inheritance solution in django. 
> >> 
> > 
> > Just to spell things out: You want to have models A, B(A), C(A) and 
> D(B), so 
> > that list(A.objects.all()) returns a list of objects of different types. 
> > 
> > This sounds like a good idea in general, but there are devils in the 
> > implementation details. In particular, I'd like to separate this issue 
> from 
> > the issue of STI -- polymorphism is an issue of processing the retrieved 
> > records, and need not be tightly coupled to the database layout. The 
> > polymorphism solution should work whether the records are fetched by the 
> > equivalent of A.objects.all() or 
> > A.objects.select_related(child_classes).all(). 
> > 
> > I think you can sort-of achieve STI by doing it the other way around: 
> Define 
> > all your hierarchy as abstract models, with one concrete model 
> inheriting all 
> > of them (I suspect any STI implementation in Django would have to do 
> something 
> > very similar "behind the scenes"). Pros and cons (as well as testing if 
> this 
> > actually works) are left as an exercise to the reader. 
> > 
> >> I know that there are third party apps which provide this, but 
> >> something like this should be in the core. 
> >> 
> > 
> > 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. 
>
> You don't even need the "type" field, you can just select_related all 
> the subclasses and then test when iteratin

Re: Why not Single Table Inheritance?

2014-05-16 Thread Carl Meyer
On 05/16/2014 04:46 AM, Shai Berger wrote:
> On Monday 12 May 2014 12:27:01 Thomas Güttler wrote:
>> Single Table Inheritance is used by ruby-on-rails and SQLAlchemy.
>>
>> Are there reasons why it is used in django?
>>
> 
> Essentially, STI is a form of database denormalization. I think Django should 
> not encourage this.

I agree.

>> I would love to see a polymorphic inheritance solution in django.
>>
> 
> Just to spell things out: You want to have models A, B(A), C(A) and D(B), so 
> that list(A.objects.all()) returns a list of objects of different types.
> 
> This sounds like a good idea in general, but there are devils in the 
> implementation details. In particular, I'd like to separate this issue from 
> the issue of STI -- polymorphism is an issue of processing the retrieved 
> records, and need not be tightly coupled to the database layout. The 
> polymorphism solution should work whether the records are fetched by the 
> equivalent of A.objects.all() or 
> A.objects.select_related(child_classes).all().
> 
> I think you can sort-of achieve STI by doing it the other way around: Define 
> all your hierarchy as abstract models, with one concrete model inheriting all 
> of them (I suspect any STI implementation in Django would have to do 
> something 
> very similar "behind the scenes"). Pros and cons (as well as testing if this 
> actually works) are left as an exercise to the reader.
> 
>> I know that there are third party apps which provide this, but
>> something like this should be in the core.
>>
> 
> 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. 

You don't even need the "type" field, you can just select_related all
the subclasses and then test when iterating over the queryset which one
exists for each record. This is what InheritanceManager in
django-model-utils does.

I don't see a need to have this in core either. It seems to me almost a
perfect example of the occasionally-useful-but-not-essential
functionality that is well served by third-party packages. (IMO concrete
model inheritance is more often than not a questionable model-design in
the first place, so Django shouldn't be adding more support around it to
encourage its use.)

Carl



signature.asc
Description: OpenPGP digital signature


Re: Why not Single Table Inheritance?

2014-05-16 Thread Shai Berger
On Monday 12 May 2014 12:27:01 Thomas Güttler wrote:
> Single Table Inheritance is used by ruby-on-rails and SQLAlchemy.
> 
> Are there reasons why it is used in django?
> 

Essentially, STI is a form of database denormalization. I think Django should 
not encourage this.

> I would love to see a polymorphic inheritance solution in django.
> 

Just to spell things out: You want to have models A, B(A), C(A) and D(B), so 
that list(A.objects.all()) returns a list of objects of different types.

This sounds like a good idea in general, but there are devils in the 
implementation details. In particular, I'd like to separate this issue from 
the issue of STI -- polymorphism is an issue of processing the retrieved 
records, and need not be tightly coupled to the database layout. The 
polymorphism solution should work whether the records are fetched by the 
equivalent of A.objects.all() or 
A.objects.select_related(child_classes).all().

I think you can sort-of achieve STI by doing it the other way around: Define 
all your hierarchy as abstract models, with one concrete model inheriting all 
of them (I suspect any STI implementation in Django would have to do something 
very similar "behind the scenes"). Pros and cons (as well as testing if this 
actually works) are left as an exercise to the reader.

> I know that there are third party apps which provide this, but
> something like this should be in the core.
> 

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. 

> There was some discussion about this [1]. One reason against it was,
> that supporting not-null is not available. But a db constraint which
> checks the type and data column could solve this.
> 

Django does not currently support arbitrary constraints well, so getting this 
right (and cross-backend) might be somewhat of a challenge; which, in turn, 
could justify including it in core. IMO, though, it would be much more useful 
to support general constraints in core, and allow this to be done by users.

Either way, concrete suggestions welcome,

Shai.

> [1]
> https://code.djangoproject.com/wiki/ModelInheritance#a1.Modelingparentrela
> tionsinSQL

-- 
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/201405161246.01677.shai%40platonix.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-05-15 Thread Christian Schmitt
This is already merged.

https://docs.djangoproject.com/en/1.6/topics/db/models/#multi-table-inheritance



Am Montag, 12. Mai 2014 11:27:01 UTC+2 schrieb guettli:
>
> Single Table Inheritance is used by ruby-on-rails and SQLAlchemy. 
>
> Are there reasons why it is used in django? 
>
> I would love to see a polymorphic inheritance solution in django. 
>
> I know that there are third party apps which provide this, but 
> something like this should be in the core. 
>
> There was some discussion about this [1]. One reason against it was, 
> that supporting not-null is not available. But a db constraint which 
> checks the type and data column could solve this. 
>
> What do you think? 
>
>Thomas Güttler 
>
> [1] 
> https://code.djangoproject.com/wiki/ModelInheritance#a1.ModelingparentrelationsinSQL
>  
>

-- 
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/7df9c4cb-daa2-41be-b08f-804dbba348e2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Why not Single Table Inheritance?

2014-05-15 Thread Tom Evans
On Thu, May 15, 2014 at 4:11 PM, Christian Schmitt
 wrote:
> This is already merged.
>
> https://docs.djangoproject.com/en/1.6/topics/db/models/#multi-table-inheritance
>

MTI is not STI, nor is it polymorphic.

Cheers

Tom

-- 
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/CAFHbX1%2BUzp1VpY7JNK4%2BCV%3Djr8Ave7Gt7jbtW6JMs9B_KVacsw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Why not Single Table Inheritance?

2014-05-12 Thread Thomas Güttler

Single Table Inheritance is used by ruby-on-rails and SQLAlchemy.

Are there reasons why it is used in django?

I would love to see a polymorphic inheritance solution in django.

I know that there are third party apps which provide this, but
something like this should be in the core.

There was some discussion about this [1]. One reason against it was,
that supporting not-null is not available. But a db constraint which
checks the type and data column could solve this.

What do you think?

  Thomas Güttler

[1] 
https://code.djangoproject.com/wiki/ModelInheritance#a1.ModelingparentrelationsinSQL

--
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/537093E5.1070002%40tbz-pariv.de.
For more options, visit https://groups.google.com/d/optout.


Re: Single table inheritance - working implementation

2012-12-23 Thread Krzysztof Jurewicz
Dnia 2012-12-21, pią o godzinie 11:05 -0800, Anssi Kääriäinen pisze:
> I went with a different approach than the patch for 1.5. At this stage
> as minimal as possible change to get_default_columns() seemed like a
> good idea. See commit a0155f35343afbfd9e98ab9aa4615f06780f697e in
> stable/1.5.x.
> 
> I patched only 1.5.x. Master will get soon different handling of the
> parent model joining in get_default_columns(). The taken approach in
> master should still allow typedmodels to work. See:
> https://github.com/akaariai/django/compare/names_to_path_to_fields#L3L254
> 
> If you have still problems in 1.5.x please tell us soon. There isn't
> too much time before the release.

Thanks for the patch, it seems to do the job - all tests pass (including
two I added today), both on 1.5.x and on 1.4.x. _fill_fields_cache still
has to be monkeypatched (I've also added similar patch for
_fill_m2m_cache), but this is no change comparing to the previous state.

I haven't yet looked through changes from your names_to_path_to_fields
branch, but tests pass on it too, which is promising.

Regards,
Krzysztof

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-12-21 Thread Anssi Kääriäinen
On 21 joulu, 16:39, Krzysztof Jurewicz 
wrote:
> On 13.12.2012 15:54, Anssi K ri inen wrote:
>
> > Second, I have created a patch which should allow your work to
> > continue working in master. See
> >https://github.com/akaariai/django/commit/94c417d2a29a0f72b26019fc38e...
> > - the idea is to change get_fields_with_model() so that it doesn't
> > return different values for proxy models compared to concrete models.
> > I think this is a good solution overall, though this change is
> > somewhat scary - get_fields_with_model is used in many places of the
> > ORM...
>
> Thanks for the patch. It causes all typedmodels' tests to pass, however
> I still have to monkey patch _fill_fields_cache to bypass some currently
> untested issues. I will investigate this further and hopefully provide
> some more detailed comments.

I went with a different approach than the patch for 1.5. At this stage
as minimal as possible change to get_default_columns() seemed like a
good idea. See commit a0155f35343afbfd9e98ab9aa4615f06780f697e in
stable/1.5.x.

I patched only 1.5.x. Master will get soon different handling of the
parent model joining in get_default_columns(). The taken approach in
master should still allow typedmodels to work. See:
https://github.com/akaariai/django/compare/names_to_path_to_fields#L3L254

If you have still problems in 1.5.x please tell us soon. There isn't
too much time before the release.

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-12-21 Thread Krzysztof Jurewicz

On 13.12.2012 15:54, Anssi Kääriäinen wrote:

Second, I have created a patch which should allow your work to
continue working in master. See
https://github.com/akaariai/django/commit/94c417d2a29a0f72b26019fc38ef400420097aa4
- the idea is to change get_fields_with_model() so that it doesn't
return different values for proxy models compared to concrete models.
I think this is a good solution overall, though this change is
somewhat scary - get_fields_with_model is used in many places of the
ORM...


Thanks for the patch. It causes all typedmodels' tests to pass, however 
I still have to monkey patch _fill_fields_cache to bypass some currently 
untested issues. I will investigate this further and hopefully provide 
some more detailed comments.


Regards,
Krzysztof

--
You received this message because you are subscribed to the Google Groups "Django 
developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-12-13 Thread Anssi Kääriäinen
On 11 joulu, 17:56, Anssi Kääriäinen <anssi.kaariai...@thl.fi> wrote:
> Would a model._meta.get_default_columns() work for you? While this
> would still be internal API, it would be hopefully less likely to
> change in ways that require extensive rewrites to 3rd party apps.

First, the ._meta.get_default_columns() I proposed above doesn't
actually make sense - the get_default_columns() does mostly things
which belong to compiler, not to ._meta.

Second, I have created a patch which should allow your work to
continue working in master. See
https://github.com/akaariai/django/commit/94c417d2a29a0f72b26019fc38ef400420097aa4
- the idea is to change get_fields_with_model() so that it doesn't
return different values for proxy models compared to concrete models.
I think this is a good solution overall, though this change is
somewhat scary - get_fields_with_model is used in many places of the
ORM...

Third, I think it is a good idea to add more abstraction between the
ORM and the Model/Fields layer. So, in this way I do support the idea
of using proxy models for single table inheritance. On the other hand
it should not be surprising if in the future "different fields than
parents" proxy models will break again - it is almost the definition
of proxy model that it has the same fields than its parent.

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-12-11 Thread Anssi Kääriäinen
On 7 joulu, 16:18, Krzysztof Jurewicz <krzysztof.jurew...@gmail.com>
wrote:
> On 29.10.2012 14:34, Krzysztof Jurewicz wrote:
>
> > In February, Craig de Stigter released django-typed-models
> > <https://groups.google.com/d/topic/django-users/63z-ejUQ1Eg/discussion>,
> > a package implementing inheritance hierarchy for Proxy models with
> > automatic type recasting. I've written a fork of it with additional
> > possibility of adding fields to subclasses, therefore achieving a single
> > table inheritance implementation similar to Ruby on Rails' STI.
>
> Refreshing this thread because it looks like my fork stopped working
> properly with recent Django master. I suspect that commit c2e1e by Anssi
> K ri inen should be blamed for this, especially the line
>
> # Skip all proxy to the root proxied model
> opts = opts.concrete_model._meta
>
> in get_default_columns method. This causes it to generate potentially
> invalid set of columns for instantiated model because children typed
> models are implemented as proxy models and they have different set of
> fields than the root model, which stores all fields from its subclasses.
> In general having richer set of columns than required wouldn't be a
> problem, but those columns are used as positional arguments in model
> constructor and are therefore mapped incorrectly.
>
> I know that proxy models are intended to have the same set of fields as
> the root model and that I was relying on a completely internal
> implementation detail, so it has no chance of being treated as a bug,
> but that being said, I wonder if maybe Django could be changed to make
> such modifications easier. Currently I see the following solutions to
> the encountered problem:
>
> 1. Do not touch Django code directly and adjust django-typed-models to
> the changes made. This would probably require writing custom Manager
> class for TypedModel with custom QuerySet class which will use custom
> Query class with custom SQLCompiler class which will finally have
> get_default_columns method copy-paste-changed. Not an elegant solution.
>
> 2. Take a completely different approach to achieve single table
> inheritance ideas are welcome.
>
> 3. Modify Django code to be more friendly to django-typed-models.
> Current behavior of SQLCompiler looks a bit hackish to me, because in
> ideal world get_default_columns shouldn't care if a model is proxy or
> not this should be handled by model class internally. So perhaps
> another layer of abstraction could be added to Django ORM to allow
> internal handling of such special cases as proxy models. This would
> ideally allow to specify STI as a completely different model type than
> proxy model.
>
> 4. Add single table inheritance as a new inheritance type in Django.
>
> I'm not very familiar with Django ORM internals and additionally I don't
> know which of the above solutions have chances of getting approval by
> core devs, so feedback is welcome.

Would a model._meta.get_default_columns() work for you? While this
would still be internal API, it would be hopefully less likely to
change in ways that require extensive rewrites to 3rd party apps.

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-12-07 Thread Krzysztof Jurewicz

On 29.10.2012 14:34, Krzysztof Jurewicz wrote:

In February, Craig de Stigter released django-typed-models
<https://groups.google.com/d/topic/django-users/63z-ejUQ1Eg/discussion>,
a package implementing inheritance hierarchy for Proxy models with
automatic type recasting. I've written a fork of it with additional
possibility of adding fields to subclasses, therefore achieving a single
table inheritance implementation similar to Ruby on Rails' STI.


Refreshing this thread because it looks like my fork stopped working 
properly with recent Django master. I suspect that commit c2e1e by Anssi 
Kääriäinen should be blamed for this, especially the line


# Skip all proxy to the root proxied model
opts = opts.concrete_model._meta

in get_default_columns method. This causes it to generate potentially 
invalid set of columns for instantiated model because children typed 
models are implemented as proxy models and they have different set of 
fields than the root model, which stores all fields from its subclasses. 
In general having richer set of columns than required wouldn't be a 
problem, but those columns are used as positional arguments in model 
constructor and are therefore mapped incorrectly.


I know that proxy models are intended to have the same set of fields as 
the root model and that I was relying on a completely internal 
implementation detail, so it has no chance of being treated as a bug, 
but that being said, I wonder if maybe Django could be changed to make 
such modifications easier. Currently I see the following solutions to 
the encountered problem:


1. Do not touch Django code directly and adjust django-typed-models to 
the changes made. This would probably require writing custom Manager 
class for TypedModel with custom QuerySet class which will use custom 
Query class with custom SQLCompiler class which will finally have 
get_default_columns method copy-paste-changed. Not an elegant solution.


2. Take a completely different approach to achieve single table 
inheritance — ideas are welcome.


3. Modify Django code to be more friendly to django-typed-models. 
Current behavior of SQLCompiler looks a bit hackish to me, because in 
ideal world get_default_columns shouldn't care if a model is proxy or 
not — this should be handled by model class internally. So perhaps 
another layer of abstraction could be added to Django ORM to allow 
internal handling of such special cases as proxy models. This would 
ideally allow to specify STI as a completely different model type than 
proxy model.


4. Add single table inheritance as a new inheritance type in Django.

I'm not very familiar with Django ORM internals and additionally I don't 
know which of the above solutions have chances of getting approval by 
core devs, so feedback is welcome.


Regards,
Krzysztof

--
You received this message because you are subscribed to the Google Groups "Django 
developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single table inheritance - working implementation

2012-10-29 Thread Craig de Stigter
Hi Krzysztof and everyone else

Thanks! Your fork looks very promising. I'll review the fork today and
possibly pull changes in if the changes aren't too disruptive. Some more
tests would probably be good.

I've added a New BSD
License<https://github.com/craigds/django-typed-models/blob/master/LICENSE.txt>
to
the repo to clear up any confusion.

Would other devs be interested in adding something like django-typed-models
to Django core? What kinds of changes would make that more likely?

Cheers
Craig de Stigter

On Tue, Oct 30, 2012 at 2:34 AM, Krzysztof Jurewicz <
krzysztof.jurew...@gmail.com> wrote:

> Hi all,
>
> In February, Craig de Stigter released 
> django-typed-models<https://groups.google.com/d/topic/django-users/63z-ejUQ1Eg/discussion>,
> a package implementing inheritance hierarchy for Proxy models with
> automatic type recasting. I've written a fork of it with additional
> possibility of adding fields to subclasses, therefore achieving a single
> table inheritance implementation similar to Ruby on Rails' STI. This is
> possible mostly thanks to metaclass magic and monkey patching.
>
> The fork's homepage is at https://github.com/KrzysiekJ/django-typed-models. 
> Note that it should be considered early alpha and there is much room for
> optimisation, code cleanup and maybe additional features. Feel free to fork
> and/or add issues.
>
> I don't know yet what to do with licensing since Craig didn't specify any
> license in the original package. Craig, please comment or send me an email.
>
> Regards,
> Krzysztof Jurewicz
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Single table inheritance - working implementation

2012-10-29 Thread Krzysztof Jurewicz
Hi all,

In February, Craig de Stigter released 
django-typed-models<https://groups.google.com/d/topic/django-users/63z-ejUQ1Eg/discussion>,
 
a package implementing inheritance hierarchy for Proxy models with 
automatic type recasting. I've written a fork of it with additional 
possibility of adding fields to subclasses, therefore achieving a single 
table inheritance implementation similar to Ruby on Rails' STI. This is 
possible mostly thanks to metaclass magic and monkey patching.

The fork's homepage is at https://github.com/KrzysiekJ/django-typed-models. 
Note that it should be considered early alpha and there is much room for 
optimisation, code cleanup and maybe additional features. Feel free to fork 
and/or add issues.

I don't know yet what to do with licensing since Craig didn't specify any 
license in the original package. Craig, please comment or send me an email.

Regards,
Krzysztof Jurewicz

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/aSgkQliZHtYJ.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-30 Thread Alex Robbins
If you need to be able to filter and search across models, you could
try haystack.

http://docs.haystacksearch.org/dev/searchqueryset_api.html#filter

I've setup a site with a real base class, done queries on that and
then returned the child classes. It worked, but it felt pretty hacky
all the way through. (You solution has a much nicer interface than
mine, so your's wouldn't feel as bad I'm guessing.)

If you go ahead and make the switch to haystack you'll be able to
search across any and all of your models, without worrying about
inheritance. I've been very happy with haystack since switching to it.

Alex

On Mar 29, 3:20 pm, Johannes Dollinger 
wrote:
> Am 29.03.2011 um 20:46 schrieb Shawn Milochik:
>
> > They can create a custom manager on the abstract class that would
> > return an iterable, perhaps using itertools.chain() of the querysets.
>
> > It depends on what they expect to do with the output of this custom
> > manager, and they'd obviously lose the ability to treat this output as
> > a queryset by using additional sorts & filters and such. But if the
> > goal is to be able to get instances from all subclasses at once then
> > this is a viable solution, FWIW.
>
> FWIW, here is an implementation that does just 
> that:https://github.com/emulbreh/shrubbery/blob/master/shrubbery/db/union.py
>
> __
> Johannes

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-30 Thread Forest Bond
Hi Jordan,

On Tue, Mar 29, 2011 at 08:40:28AM -0700, Jordan MacDonald wrote:
> I'm sure this subject has been beaten to death, but I haven't found an
> answer to a simple scenario and I'm wondering why this hasn't been
> addressed before.
> 
> I have three models, structured like so:
> 
> Document
> -Presentation
> -Spreadsheet
> 
> Document is never instantiated on its own; a prime candidate for an
> abstract base class. However, there are times where I want to list/
> search across all documents, and I'd like to be able to write
> Document.objects.all(). I'd then like to be able to iterate over this
> enumerable and have each object cast to its proper class.
> 
> This is something accomplished with single table inheritance in Rails;
> why don't we have the equivalent in Django?
> 
> I know I could just use the Document class and have a type field, but
> then I have to do all of the type checking legwork manually. I was
> hoping Django would handle normalizing/denormalizing as part of the
> ORM. In essence, creating its own type field automatically in the back-
> end and casting each object to the appropriate class based on the
> string value in this field.
> 
> Does anyone know why this isn't available? Is there an equally
> efficient method of modeling this approach of which I am unaware?

I haven't used it, but maybe you should look into django_polymorphic:

http://bserve.webhop.org/django_polymorphic/

Thanks,
Forest
-- 
Forest Bond
http://www.alittletooquiet.net
http://www.pytagsfs.org


signature.asc
Description: Digital signature


Re: Single Table Inheritance

2011-03-29 Thread Johannes Dollinger

Am 29.03.2011 um 20:46 schrieb Shawn Milochik:

> They can create a custom manager on the abstract class that would
> return an iterable, perhaps using itertools.chain() of the querysets.
> 
> It depends on what they expect to do with the output of this custom
> manager, and they'd obviously lose the ability to treat this output as
> a queryset by using additional sorts & filters and such. But if the
> goal is to be able to get instances from all subclasses at once then
> this is a viable solution, FWIW.

FWIW, here is an implementation that does just that: 
https://github.com/emulbreh/shrubbery/blob/master/shrubbery/db/union.py

__
Johannes

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Carl Meyer


On 03/29/2011 02:46 PM, Shawn Milochik wrote:
> I'm not proposing a change to Django itself or suggesting that this
> should be a standard practice. I do think that this is a fairly clean
> solution for an individual to use to solve this problem if they have
> it.
> 
> They can create a custom manager on the abstract class that would
> return an iterable, perhaps using itertools.chain() of the querysets.

Ah, I didn't realize that's the direction you were headed. Yeah, you can
do this, and I've done it; it starts to hurt as soon as you want, say,
sorting + pagination without pulling all of both tables into memory.

> It depends on what they expect to do with the output of this custom
> manager, and they'd obviously lose the ability to treat this output as
> a queryset by using additional sorts & filters and such. But if the
> goal is to be able to get instances from all subclasses at once then
> this is a viable solution, FWIW.

Yup.

Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Shawn Milochik
On Tue, Mar 29, 2011 at 2:21 PM, Carl Meyer  wrote:
> Hi Shawn,
>
> What you've outlined here is certainly possible (and yes, you'd need to
> subclass the ModelBase metaclass). I haven't looked at the abstract
> inheritance stuff recently, but I think there would be some alternative
> ways for the abstract base to know about its children that wouldn't
> require the metaclass assignment. However: getting the list of
> subclasses is (less than) half the battle; the trickier part is giving
> the ORM the capability to do UNION queries on similar tables, so you can
> get results from multiple tables in a single QuerySet.

Carl,

Thanks for the explanation. That does make sense and I see where it
gets really tricky when you delve into the ORM.

I'm not proposing a change to Django itself or suggesting that this
should be a standard practice. I do think that this is a fairly clean
solution for an individual to use to solve this problem if they have
it.

They can create a custom manager on the abstract class that would
return an iterable, perhaps using itertools.chain() of the querysets.

It depends on what they expect to do with the output of this custom
manager, and they'd obviously lose the ability to treat this output as
a queryset by using additional sorts & filters and such. But if the
goal is to be able to get instances from all subclasses at once then
this is a viable solution, FWIW.

Shawn

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Carl Meyer
Hi Shawn,

On 03/29/2011 01:28 PM, Shawn Milochik wrote:
> Hopefully someone on the core dev team can let me know if this is
> possible in Django. If so, it will solve this problem.
> I am not familiar with custom metaclass stuff done within models.Model.
> 
> 1. Create a custom metaclass as described in "Pro Python," page 124.
> 
> 2. Add this metaclass to the abstract model.
> 
> This would allow the base-class to be aware of its subclasses and have
> a class method that returns a queryset of them.
> 
> Further detail:
> This simply amounts to creating a list object in the abstract base
> class. Each time a subclass is instantiated, that class is added to
> the parent class's list. That's all. That list could be used in a
> custom manager to get the desired queryset.
> 
> What I don't know is how nicely this will play with the existing
> metaclass work in Django. It seems that a metaclass can be easily made
> by subclassing the one used for models.Model instead of the default
> 'type,' but this is beyond my experience level. Is this a reasonable
> approach?

What you've outlined here is certainly possible (and yes, you'd need to
subclass the ModelBase metaclass). I haven't looked at the abstract
inheritance stuff recently, but I think there would be some alternative
ways for the abstract base to know about its children that wouldn't
require the metaclass assignment. However: getting the list of
subclasses is (less than) half the battle; the trickier part is giving
the ORM the capability to do UNION queries on similar tables, so you can
get results from multiple tables in a single QuerySet.

Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Jeremy Dunck
On Tue, Mar 29, 2011 at 11:40 AM, Carl Meyer  wrote:
> On 03/29/2011 12:40 PM, Jeremy Dunck wrote:
>> What about keeping abstract inheritance in this case, but allowing
>> Document.objects.* to work by returning instances of the subclasses.
>> Filtering, etc. would only work based on the Document base class.
>>
>> It would mean doing some unions, but would still fit the use case
>> pretty well, I think.
>
> I'd certainly be intrigued to look at a patch that implemented that.

I made a ticket; hopefully I'll get around to it some day:
http://code.djangoproject.com/ticket/15711

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Shawn Milochik
Hopefully someone on the core dev team can let me know if this is
possible in Django. If so, it will solve this problem.
I am not familiar with custom metaclass stuff done within models.Model.

1. Create a custom metaclass as described in "Pro Python," page 124.

2. Add this metaclass to the abstract model.

This would allow the base-class to be aware of its subclasses and have
a class method that returns a queryset of them.

Further detail:
This simply amounts to creating a list object in the abstract base
class. Each time a subclass is instantiated, that class is added to
the parent class's list. That's all. That list could be used in a
custom manager to get the desired queryset.

What I don't know is how nicely this will play with the existing
metaclass work in Django. It seems that a metaclass can be easily made
by subclassing the one used for models.Model instead of the default
'type,' but this is beyond my experience level. Is this a reasonable
approach?

Shawn

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Jordan MacDonald
Cool.

Well, maybe I can look into how abstract base classes are currently
implemented and see if there's a way to generate query sets for all
derived classes from the parent.

Thanks for the insight!

On Mar 29, 12:40 pm, Carl Meyer  wrote:
> On 03/29/2011 12:40 PM, Jeremy Dunck wrote:
>
> > What about keeping abstract inheritance in this case, but allowing
> > Document.objects.* to work by returning instances of the subclasses.
> > Filtering, etc. would only work based on the Document base class.
>
> > It would mean doing some unions, but would still fit the use case
> > pretty well, I think.
>
> I'd certainly be intrigued to look at a patch that implemented that.
>
> Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Carl Meyer
On 03/29/2011 12:40 PM, Jeremy Dunck wrote:
> What about keeping abstract inheritance in this case, but allowing
> Document.objects.* to work by returning instances of the subclasses.
> Filtering, etc. would only work based on the Document base class.
> 
> It would mean doing some unions, but would still fit the use case
> pretty well, I think.

I'd certainly be intrigued to look at a patch that implemented that.

Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: Single Table Inheritance

2011-03-29 Thread Jeremy Dunck
On Tue, Mar 29, 2011 at 11:11 AM, Carl Meyer  wrote:
> Hi Jordan,
>
> On 03/29/2011 11:40 AM, Jordan MacDonald wrote:
>> I have three models, structured like so:
>>
>> Document
>> -Presentation
>> -Spreadsheet
...

>> I'd like to be able to write
>> Document.objects.all(). I'd then like to be able to iterate over this
>> enumerable and have each object cast to its proper class.
...
> I'm not sure I'd want to have yet another variety of inheritance as a
> first-class feature of the Django ORM; the array of existing options
> with MTI, abstract inheritance, and proxy models is quite confusing
> enough to new users!

What about keeping abstract inheritance in this case, but allowing
Document.objects.* to work by returning instances of the subclasses.
Filtering, etc. would only work based on the Document base class.

It would mean doing some unions, but would still fit the use case
pretty well, I think.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Single Table Inheritance

2011-03-29 Thread Jordan MacDonald
I'm sure this subject has been beaten to death, but I haven't found an
answer to a simple scenario and I'm wondering why this hasn't been
addressed before.

I have three models, structured like so:

Document
-Presentation
-Spreadsheet

Document is never instantiated on its own; a prime candidate for an
abstract base class. However, there are times where I want to list/
search across all documents, and I'd like to be able to write
Document.objects.all(). I'd then like to be able to iterate over this
enumerable and have each object cast to its proper class.

This is something accomplished with single table inheritance in Rails;
why don't we have the equivalent in Django?

I know I could just use the Document class and have a type field, but
then I have to do all of the type checking legwork manually. I was
hoping Django would handle normalizing/denormalizing as part of the
ORM. In essence, creating its own type field automatically in the back-
end and casting each object to the appropriate class based on the
string value in this field.

Does anyone know why this isn't available? Is there an equally
efficient method of modeling this approach of which I am unaware?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.