Hello,

I've run into a case where my code works with a single engine binding
but breaks if bound to multiple engines.  I'm doing some things that
might be considered weird - mixing joined and single table inheritance
to reduce data storage, inheriting mappers from other derived mappers.
The exception I get looks like my Session hasn't been bound:

sqlalchemy.exc.UnboundExecutionError: Could not locate a bind configured on 
mapper Mapper|CiscoSwitch|switch or this Session

I hacked up a quick stand-alone script.  If I bind to a single engine
with orm.sessionmaker(bind=engine), everything works fine.  But if I
bind to multiple engines via something like
orm.scoped_session(orm.sessionmaker(binds=binds)), commits fail.

Sorry for the long code sample below - takes a bit to get my example
going.  Swapping the sessionmaker as described above fixes the below
code.

Shouldn't this work on SA 0.5.8?


-------------------------------------------------------------------------
from sqlalchemy import *
from sqlalchemy import orm

metadata = MetaData()

class DeviceBase(object):
    pass

class Switch(DeviceBase):
    pass
class CiscoSwitch(Switch):
    pass
class JuniperSwitch(Switch):
    pass

class Router(DeviceBase):
    pass
class CiscoRouter(Router):
    pass
class JuniperRouter(Router):
    pass


device_table = Table('device', metadata,
                     Column('id', Integer, primary_key=True),
                     Column('model', Integer, nullable=False))

switch_table = Table('switch', metadata,
                     Column('id', Integer, ForeignKey('device.id'), 
primary_key=True),
                     Column('ussid1', Integer, ForeignKey('switch.id')),
                     Column('ussid2', Integer, ForeignKey('switch.id')))

router_table = Table('router', metadata,
                     Column('id', Integer, ForeignKey('device.id'), 
primary_key=True))


device_mapper = orm.mapper(DeviceBase, device_table, 
polymorphic_on=device_table.c.model,
                       polymorphic_identity=0)

switch_mapper = orm.mapper(Switch, switch_table, inherits=device_mapper, 
polymorphic_identity=1,
                       properties={'upstream1': orm.relation(Switch, 
remote_side=[switch_table.c.id], 
primaryjoin=switch_table.c.ussid1==switch_table.c.id),
                                   'upstream2': orm.relation(Switch, 
remote_side=[switch_table.c.id], 
primaryjoin=switch_table.c.ussid2==switch_table.c.id)})
cisco_mapper = orm.mapper(CiscoSwitch, inherits=switch_mapper, 
polymorphic_identity=2)
juniper_mapper = orm.mapper(JuniperSwitch, inherits=switch_mapper, 
polymorphic_identity=3)

router_mapper = orm.mapper(Router, inherits=device_mapper, 
polymorphic_identity=4)
ciscorouter_mapper = orm.mapper(CiscoRouter, inherits=router_mapper, 
polymorphic_identity=5)
juniperrouter_mapper = orm.mapper(JuniperRouter, inherits=router_mapper, 
polymorphic_identity=6)

engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)
binds = { device_table : engine,
          switch_table : engine }

Session = orm.scoped_session(orm.sessionmaker(binds=binds))
session = Session()

r1 = CiscoRouter()
r2 = JuniperRouter()

parent1 = CiscoSwitch()
parent2 = CiscoSwitch()

child1 = JuniperSwitch()
child1.upstream1 = parent1
child1.upstream2 = parent2
child2 = JuniperSwitch()
child2.upstream1 = parent1
child2.upstream2 = parent2

session.add_all([r1, r2])
session.add_all([parent1, parent2, child1, child2])
session.commit()


-- 
Ross Vandegrift
r...@kallisti.us

"If the fight gets hot, the songs get hotter.  If the going gets tough,
the songs get tougher."
        --Woody Guthrie

Attachment: signature.asc
Description: Digital signature

Reply via email to