OK, the issue here is pretty common, but I wanted to also see how
well this example works in the 0.4 branch where its a lot easier to
do this and that led to some interesting discoveries.
anyway, whats happening here is that you need a second
polymorphic_union in your Managers mapper. without it, it loads a
"Manager" row and a "Boss" row (both represented in employees/
managers, but when it tries to create a "Boss" object, theres no
"boss.person_id" column present (nor is there a "powers" column). so
manager_mapper becomes;
manager_join = polymorphic_union({
'manager':employees.join(managers),
'boss':employees.join(managers).join(boss),
}, None, 'pjoin')
manager_mapper = mapper(Manager, managers,
inherits=person_mapper,
select_table = manager_join,
polymorphic_identity='manager')
But another problem that will occur with these mappings are that
youll get "boss" rows in your various employees.join(managers) as
well since they arent excluding "boss" rows...so you also probably
want to adjust these unions so that the "manager" part of it adds
"where type='manager'" to limit the rows.
so i was playing with this, and it *seems* like you can *also* just
use straight outerjoins, i.e. not even bother with UNION ALL. I need
to study this further since we've been using the UNION thing for
quite some time and its not clear to me what the reason was for all
that...this mapping would look like:
person_join = employees.outerjoin(managers).outerjoin(boss)
manager_join = employees.join(managers).outerjoin(boss)
person_mapper = mapper(Employee, employees,
select_table=person_join,
polymorphic_on=employees.c.type,
polymorphic_identity='person')
manager_mapper = mapper(Manager, managers,
inherits=person_mapper,
select_table = manager_join,
polymorphic_identity='manager')
mapper(Boss, boss,
inherits=manager_mapper,
polymorphic_identity='boss')
see if you can get that one to break....this would make polymorphic
selecting a lot easier since the unions are tough to construct.
in the 0.4 series, you can also skip all this "select_table" union/
outerjoin stuff altogether - SA knows how to issue additional queries
to load the extra data, and you neednt use the "select_table"
argument at all - just polymorphic_on/polymorphic_identity. (the
expense is that it issues more queries to load subclass rows). you
can try 0.4 by checking out the branch from SVN.
On Jun 7, 2007, at 8:20 PM, Daniele Varrazzo wrote:
> from sqlalchemy import *
> metadata = BoundMetaData('sqlite://')
>
> # Database metadata
>
> employees = Table('employees', metadata,
> Column('person_id', Integer, primary_key=True),
> Column('name', String(50)),
> Column('type', String(30)))
>
> managers = Table('managers', metadata,
> Column('person_id', Integer,
> ForeignKey('employees.person_id'),
> primary_key=True),
> Column('manager_data', String(50)))
>
> boss = Table('boss', metadata,
> Column('person_id', Integer,
> ForeignKey('managers.person_id'),
> primary_key=True),
> Column('powers', String(50)))
>
> metadata.create_all()
>
>
> # Python classes
>
> class Employee(object): pass
> class Manager(Employee): pass
> class Boss(Manager): pass
>
>
> # Mapping objects
>
> person_join = polymorphic_union({
> 'person':employees.select(employees.c.type=='person'),
> 'manager':employees.join(managers),
> 'boss':employees.join(managers).join(boss),
> }, None, 'pjoin')
>
> person_mapper = mapper(Employee, employees,
> select_table=person_join,
> polymorphic_on=person_join.c.type,
> polymorphic_identity='person')
>
> manager_mapper = mapper(Manager, managers,
> inherits=person_mapper,
> polymorphic_identity='manager')
>
> mapper(Boss, boss,
> inherits=manager_mapper,
> polymorphic_identity='boss')
>
>
> # Testing serialization
>
> ses = create_session()
> for emp in [ Employee(), Manager(), Boss() ]:
> ses.save(emp)
> ses.flush()
> ses.clear()
>
> #print ses.query(Employee).select() # this works
> print ses.query(Manager).select() # this doesn't
> #print ses.query(Boss).select() # this works too
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---