On Sep 3, 2008, at 8:47 PM, Sam Magister wrote:

>
> I was wondering if it is possible to set up joined table inheritance
> so that a subclass inherits from more than one base table. To extend
> the example given in the documentation, we would have a base class
> 'Employee' and a base class 'Citizen' such that an 'Engineer' would
> inherit from both Employee and Citizen classes and have independent
> 'citizen_id' and 'employee_id'. One could imagine other classes that
> only inherit from either employee or citizen.
>
> employees = Table('employees', metadata,
>   Column('employee_id', Integer, primary_key=True),
>   Column('employee_type', String(30), nullable=False)
> )
>
> citizens = Table('citizens', metadata,
>   Column('citizen_id', Integer, primary_key=True),
>   Column('citizen_type', String(30), nullable=False)
> )
>
> An engineer who is both an employee and a citizen would have am
> employee_id and a citizen_id:
>
> engineers = Table('engineers', metadata,
>   Column('id', Integer, primary_key=True)
>   Column('employee_id', Integer,
> ForeignKey('employees.employee_id')),
>   Column('citizen_id', Integer, ForeignKey('citizens.citizen_id')),
>   Column('engineer_info', String(50)),
> )

This pattern doesnt entirely make sense - the "citizen_type" and  
"employee_type" columns seem superfluous and redundant against each  
other, since we really can't load Engineer rows without querying all  
three tables.  In that sense it takes on all the limitations of  
concrete table inheritance, which doesnt use a "type" column at the  
table level.

Also, a key aspect of SQLA's polymorphic loading capability is that a  
mapper is aware of all of its possible subtypes.   If multiple  
inheritance is part of that, the geometry of "what are all my  
subtypes?" becomes a more chaotic.  We'd have to join to every table  
in the whole hierarchy to identify the type.   To be fair I think this  
is a behavior that Hibernate supports but they only support it for  
single inheritance (and they also boast of how difficult it was to  
implement).    SQLA's usual notion of "primary key" with respect to  
joined table inheritance wouldn't work here either (engineer's PK is  
either (x, y) or (x, y, z), employee and citizen are just (x)),  
suggesting again a more "concrete" notion - you need to select from  
the subclass table in order to locate the object, and the primary key  
itself does not provide enough information to select the appropriate  
subclass table.

The standard patterns for "multiple" inheritance in SQL are listed at 
http://www.agiledata.org/essays/mappingObjects.html#MappingMultipleInheritance 
  .  There you'll find examples of concrete, single, and joined table  
"multiple" inheritance.

You can certainly map to any of the hierarchies indicated in that  
article, but you wouldn't be able to take advantage of SQLA's  
"polymorphic" capabilities, which are designed to only handle single  
inheritance.   You'd really want to make your Engineer(Employee,  
Citizen) class and just map it to  
engineers.join(citizens).join(employees).   That would get your schema  
going, just without SQLA having any awareness of the "inheritance"  
portion of it, and is extremely similar to a plain concrete setup,  
which is pretty much all you'd get anyway without the ability to load  
polymorphically.

> For my application, this pattern is important (the above example is
> only an example of the pattern, I'm not really modeling employees and
> citizens) and I was wondering if anyone had any suggestions as to how
> to go about implementing this functionality, which I'm planning on
> doing.

if you mean "implementing" within SQLAlchemy itself such that its core  
notion of inheritance is modified to support multiple base classes  
spread across multiple tables, this would be an enormously difficult  
feature to implement.    For polymorphic loading, at the very least  
SQLA would need to lose its dependency on "discriminator" columns and  
learn to just look for row presence in a table as evidence of  
belonging to a certain type (that alone is not necessarily a bad  
thing, as Hibernate does this too).

It would also need to learn to create joins to other tables  
corresponding to horizontal and vertical relationships, and be able to  
guess the type of a row based on a complicated equation of row  
presence.  All of the ambigousness introduced by multiple inheritance,  
like diamond patterns and such would also have to be dealt with.    So  
I'm not really sure that even with the best of efforts, multiple  
inheritance could ever be nearly as transparent as single  
inheritance.   Beyond the effort level to implement, I'd be very  
concerned about the complexity it would introduce to SQLA's  
internals.    The use case itself seems exceedingly rare.     While a  
recipe that "gets the job done" is entirely fine in this case, I'm  
fairly skeptical of functionality like this as a core feature.



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
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