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
[email protected]
"If the fight gets hot, the songs get hotter. If the going gets tough,
the songs get tougher."
--Woody Guthrie
signature.asc
Description: Digital signature
