On Nov 8, 2006, at 12:04 AM, Randall Smith wrote:

>
> That leads to the part I'm stuck on; mapper inheritance.  When  
> finished,
> session.query(Employee).select() should list all employee as instances
> of their specific classes and session.query(Engineer).select() should
> list all engineers ...  So how do I set up the mappers to accomplish
> this?  The polymorphic_on/polymorphic_identity method seems to only
> accommodate 1 level of inheritance.  The Engineer mapper will inherit
> from the Employee mapper, but will have no polymorphic_identity.
>

beacuse the polymorphic union is manually constructed, if you want  
multi-level loading you have to construct individual polymorphic  
unions for each class from which you want to load polymorphically,  
and specify it as the select_table argument for each mapper that  
requires polymorphic loading.

when you say query(Employee).select(), it uses the mapper assigned to  
Employee and the select_table which you specified.

when you say query(Engineer).select(), the Employee mapper is not  
used; it uses the Engineer mapper and the select_table specified on  
*that* mapper.

it *is* in the cards that the polymorphic_union query will probably  
become more automated in a future release.  the polymorphic_union  
function itself is the first version of this automation and im sort  
of road testing just that level of automation to start with.

for your other questions:

1. a mapper inheriting from another mapper is mostly significant with  
regards to the persistence of object instances, i.e. during flush(),  
since there is an entire set of dependencies between inheriting  
classes.  with regards to selecting and populating, an inherited  
mapper inherits the properties of the parent mapper, i.e. the column- 
mapped attributes as well as the relation()'s which you have attached  
to the parent mapper.  when you add the "polymorphic_identity" into  
the mix, an additional set of logic occurs during the _instance()  
method on mapper, which is the method that receives a row and  
produces an object instance.  it just looks at the "polymorphic_on"  
column in each incoming row and delegates the instance construction  
to the appropriate mapper.

so the loading of polymorphic entities can be totally understood by  
just looking at the queries issued, and then looking at the rows that  
come back.  each row needs some kind of identifying type in order to  
determine the class to be instantiated.

2. the "concrete" flag refers to an inheriting mapper that stores its  
entire set of data in its own table, and does not need any columns  
from the parent mapper's table in order to map an instance.  so to  
load a particular class of entity involves querying only one table,  
and no join is required.  this flag is only meaningful in inheritance  
relationships.  I just noticed that one of my docstrings in the  
constructor of the Mapper class is incorrect regarding local_table  
and concrete as well, in case that was confusing you. it should refer  
to "single" table inheritance.

3. select_table should be used when you want polymorphic loading from  
a particular mapper, and the inheritance relationship spans over more  
tables than just what is defined in that mapper.  this means you use  
it for joined table and concrete inheritance, but not single table.   
if a set of mappers mixes the approaches, then youd probably want to  
use select_table.



--~--~---------~--~----~------------~-------~--~----~
 You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to