vladimir: changeset 1510 contains a fairly dramatic change to the unit of work to account for the issue this test raises. i should add some extra unit tests for it as well. so its working now (although, tread carefully...) the only change to your test I would suggest is to not redefine your "backref" property for 'specification' and instead do it inline: specification_mapper = mapper(SpecLine, specification_table, properties=dict( master=relation(Assembly, foreignkey=specification_table.c.master_id, primaryjoin=specification_table.c.master_id==products_table.c.product_id, lazy=True, backref=backref('specification', primaryjoin=specification_table.c.master_id==products_table.c.product_id), uselist=False), slave=relation(Product, foreignkey=specification_table.c.slave_id, primaryjoin=specification_table.c.slave_id==products_table.c.product_id, lazy=True, uselist=False), quantity=specification_table.c.quantity, ) ) the issue was that the topological sorting, which determines which kind of objects to save in what order as well as matching new primary key ids to foreign objects, was wrong. It now considers inheritance hierarchies to all be under one "task" instead of breaking them up. to distill your program down to the actual issue is this: from sqlalchemy import * metadata = BoundMetaData('sqlite://', echo=True) products_table = Table('products', metadata, Column('product_id', Integer, primary_key=True), Column('product_type', String(128)), Column('name', String(128)), ) specification_table = Table('specification', metadata, Column('spec_line_id', Integer, primary_key=True), Column('slave_id', Integer, ForeignKey("products.product_id"), nullable=True), ) class Product(object): def __init__(self, name): self.name = name def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.name) class Detail(Product): pass class SpecLine(object): def __init__(self, slave=None): self.slave = slave def __repr__(self): return '<%s %s>' % ( self.__class__.__name__, getattr(self.slave, 'name', None) ) product_mapper = mapper(Product, products_table, polymorphic_on=products_table.c.product_type, polymorphic_identity='product') detail_mapper = mapper(Detail, inherits=product_mapper, polymorphic_identity='detail') specification_mapper = mapper(SpecLine, specification_table, properties=dict( slave=relation(Product, foreignkey=specification_table.c.slave_id, primaryjoin=specification_table.c.slave_id==products_table.c.product_id, lazy=True, uselist=False), ) ) metadata.create_all() session = create_session(echo_uow=True) s = SpecLine(slave=Product(name='p1')) s2 = SpecLine(slave=Detail(name='d1')) session.save(s) session.save(s2) session.flush() session.clear() print session.query(SpecLine).select() On May 25, 2006, at 7:24 AM, Vladimir Iliev wrote:
|
- [Sqlalchemy-users] can't assign to a polymorphic property Vladimir Iliev
- Re: [Sqlalchemy-users] can't assign to a polymorphic p... Michael Bayer