just a theoretical comment... so instead of relying on SA mapper logic 
to automaticaly put the discriminator/s, u are doing it on a level 
above, in a way - as SA does not know about the (multiple) 
inheritance that those imply. can be useful as an approach for 
other 'beyond SA' things... 
will it work for multilevel inheritance? 
btw i would not call it concrete-table inh, as Engineer has only 
foreignkeys to other tables (like joined-table) and not their data 
columns. but it isnt joined-table either. inbetween...

On Friday 05 September 2008 21:56:28 Sam Magister wrote:
> I've come up with an implementation based on concrete table
> inheritance, without touching any SQLA internals like Michael
> suggested. I've also added a discriminator to both base classes,
> 'citizen_type' and 'employee_type'. The discriminator is set via
> the before_insert() method of a MapperExtension which extends the
> Engineer mapper.
>
> I realize that going this way forfeits the advantages of the
> polymorphic querying, but that's ok for my application. I can still
> get the same resuts, it just takes a few subqueries after I query
> one of the base classes.
>
> I've run a few tests with this setup and it seems to work - the
> crux is in the engineers.join(employees).join(citizens) table
> definition in the Engineer mapper and the ForeignKey constraints.
>
> I just wanted to put this out there to see if anyone notices any
> issues I am not anticipating or if this model might be helpful to
> someone in the future who wants to inherit from two independent
> base classes. I realize that the Engineers inheriting from
> Employees and Citizens example is a bit forced, sorry about that.
> This is not my actual application, I just wanted to give a simple
> example. Perhaps a better application would be having 'Dragon'
> inheriting from both 'Bird' and 'Lizard', as given in the Agile
> Data essay linked to earlier.
>
> Here's the setup:
>
> 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 an
> 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)),
> )
>
> And the classes look like:
>
> class Employee(object):
>     pass
>
> class Citizen(object):
>     pass
>
> class Engineer(Employe, Citizen):
>     pass
>
> This is the mapper extension for setting the discriminators:
>
> class EngineerExtension(MapperExtension):
>
>   def __init__(self):
>     MapperExtension.__init__(self)
>
>   def before_insert(self, mapper, connection, instance):
>     instance.employee_type = 'engineer'
>     instance.citizen_type = 'engineer'
>
> And the mappers:
>
> mapper(Engineer, engineers.join(employees).join(citizens),
> extension=EngineerExtension())
> mapper(Employee, employees)
> mapper(Citizen, citizens)
>
> Any comments on this setup are welcome!
>
> Sam

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