i went for polymorphic asociation on my multiple inheritances / multiple aspects. it gives even more freedom than what strict inheritance needs.
the examples around ruby-on-rails are for one2many/many2one: http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations sqlalchemy/examples/poly_assoc/ i have a many2many version, http://dbcook.svn.sourceforge.net/viewvc/dbcook/trunk/dbcook/usage/polymassoc.py the idea: the assoc.table points to the value and to all the possible owners (via foreign keys), with only one of the owners set-up for each record. this can probably be extended to point to multiple types of values too. ciao svil On Thursday 04 September 2008 06:25:53 Michael Bayer wrote: > 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#MappingMultiple >Inheritance . 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 -~----------~----~----~----~------~----~------~--~---
