Hi,
I tried to eager load some data from class that have reference to
polymorhic class. The object model is:  class Base inherited by both
Manager and Address, Managers has reference to Address - when I stop
here SA can eager loading the addresses of managers. The problem arise
when I add another class MailAddress that inherits Address - in this
case address of Managers are simply lazy loaded, despite  that it is
explicitly set to be eager. Maybe the problem is that somehow
polymorhic and eager cannot be combined?
please advice
TIA
Stefan


Below is example of code demonstrating the behavior:
from sqlalchemy import *
db_sqlite = create_engine( 'sqlite:///:memory:')
MODEL_WITH_MAIL_ADDR = 1   # 1 - WITH MAILADDRESS, 0 - WITHOUT
MAILADDRESS

def checkWith( db):
    meta = BoundMetaData( db)
    meta.engine.echo = 0
    table_Base = Table( 'base', meta,
        Column( 'discriminator', type= String, ),
        Column( 'id', Integer, primary_key= True, ),
    )
    table_Manager = Table( 'manager', meta,
        Column( 'address_id', Integer, ForeignKey( 'address.id', name=
'address_id_fk',), ),
        Column( 'name', type= String, ),
        Column( 'id', Integer, ForeignKey('base.id', name=
'manager_inh_fk'), primary_key= True, ),
    )
    table_Address = Table( 'address', meta,
        Column( 'country', type= String, ), #for case without
mailaddress
        Column( 'city', type= String, ),
        Column( 'id', Integer, ForeignKey('base.id', name=
'address_inh_fk'), primary_key= True, ),
    )
    if MODEL_WITH_MAIL_ADDR:
        table_Mail = Table( 'mailaddress', meta,
            Column( 'country', type= String, ),
            Column( 'id', Integer, ForeignKey('base.id', name=
'address_inh_fk'), primary_key= True,
        )
    class Base( object):
        def set( me, **kargs):
            for k,v in kargs.iteritems(): setattr( me, k, v)
            return me
        def __str__(me): return str(me.__class__.__name__)
+':'+str(me.name)
        __repr__ = __str__
    class Manager( Base):
        def __str__(me):
            res = Base.__str__(me)+':'+str(me.address.city)
            if MODEL_WITH_MAIL_ADDR:
                res += ':'+str(me.address.country)
            return res
        __repr__ = __str__
    class Address( Base):   pass
    class MailAddress( Address):   pass
    meta.create_all()
    def make_mappers():
        propdic = {
                'manager':  table_Base.join( table_Manager, onclause=
(table_Manager.c.id==table_Bas
                'address':  table_Base.join( table_Address, onclause=
(table_Address.c.id==table_Bas
                'base':
table_Base.select( table_Base.c.discriminator=='base'),
        }
        if MODEL_WITH_MAIL_ADDR:
            propdic.update( { 'mailaddress':
table_Base.join( table_Address.join( table_Mail
                            , onclause=
(table_Mail.c.id==table_Address.c.id))
                        , onclause=
(table_Address.c.id==table_Base.c.id)
                    ), })
            join_Address = polymorphic_union( {
                'address':  table_Base.join( table_Address, onclause=
(table_Address.c.id==table_Bas
                'mailaddress':  table_Base.join( table_Address,
                    onclause=
(table_Address.c.id==table_Base.c.id)).join( table_Mail,
                        onclause=
(table_Mail.c.id==table_Address.c.id)
                    ),
            }, None)
        join_Base = polymorphic_union( propdic, None)
        mapper_Base = mapper( Base, table_Base, select_table=
join_Base
            , polymorphic_on= join_Base.c.discriminator,
polymorphic_identity= 'base')
        mapper_Manager = mapper( Manager, table_Manager,
            properties= { 'address' : relation( Address, primaryjoin=
(table_Manager.c.address_id==t
            , inherits= mapper_Base
            , inherit_condition= (table_Manager.c.id==table_Base.c.id)
            , polymorphic_identity='man'
        )        mapper_Address = mapper( Address, table_Address
            , inherits= mapper_Base
            , inherit_condition= (table_Address.c.id==table_Base.c.id)
            , polymorphic_identity='adr'
        )
        if MODEL_WITH_MAIL_ADDR:
            mapper_Address.select_table = join_Address
            mapper_MailAddress = mapper( MailAddress, table_Mail
                , inherits= mapper_Address
                , inherit_condition=
(table_Mail.c.id==table_Address.c.id)
                , polymorphic_identity='mai'
            )

    make_mappers()
    if not MODEL_WITH_MAIL_ADDR:
        MailAddress = Address
    c = Manager().set( name= 'pencho')
    d = Manager().set( name= 'torencho')
    e = Manager().set( name= 'mnogoVojdMalkoIndianec')
    f = MailAddress().set( city= 'varna', country= 'BG')
    g = MailAddress().set( city= 'sofia', country= 'RU')
    h = MailAddress().set( city= 'burga', country= 'US')
    c.address, d.address, e.address = f, g, h
    session = create_session()
    session.save(c)
    session.save(d)
    session.save(e)
    session.save(f)
    session.save(g)
    session.save(h)
    session.flush()

    from sqlalchemy.ext.selectresults import SelectResults
########### lazy/eager with hierarchy
    if 10:
        session.clear()
        meta.engine.echo = 1
        q = SelectResults( session.query( Manager).options([
                eagerload( 'address'),
            ]))
        print 40*'-', 'EAGER to address (NOT WORKING WHEN REF TO POLY):
\n', list( q )

checkWith( db_sqlite)


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