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