Michael,

As always, I appreciate the obviously significant amount of thought and 
time you put into this response.  I'll be referencing it for some time 
as I seek to increase my understanding.

I've got comments and questions that I worked in below.

Michael Bayer wrote:
> 
> 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.

My current (and only) union looks like this:

employee_union = polymorphic_union(
     {
     'ac': accountants,
     'me': mechanical_engineers,
     'ce': chemical_engineers,
     },
     'type'
)

accountants, mechanical_engineers, and chemical_engineers are all 
selectables from the employees table that create a "type" field.  This 
union covers all of the records and I don't know what other unions would 
be useful.

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

employee_mapper = mapper(Employee, employees,
     select_table=employee_union, polymorphic_on=employee_union.c.type)
mapper(ChemicalEngineer, employees, select_table=employee_union,
        polymorphic_identity='ce')
...MechanicalEngineer
...Accountant
??? Where does Engineer mapper fit in?

The select_table (I think) would be employee_union.  The mappers for 
Accountant, MechanicalEngineer, and ChemicalEngineer all inherit from it 
and define polymorphic_on = ('ac', 'me', 'ce') respectively.  That works 
great except that I don't know where the Engineer mapper fits into the 
picture.  Maybe the answer is in next statement.

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

Does that mean that the Engineer mapper does not inherit from the 
Employee mapper?  If I want to do query(Engineer).select() and get ME 
and CE instances, then ME and CE mappers must inherit from Engineer 
don't they?  But they're already defined as inheriting from employee.

Sorry it I've totally missed your point.  I'll keep reading over this 
message and trying things.

-Randall

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