this is a side effect of "declarative" which I covered in my pycon tutorial. Child1.id is a map of both "child1.id" and "parent.id", since they are mapped under the same name. you can see this if you say Child1.id.property.columns. the non-foreign key parent.id takes precedence.
the easy solution is to split them up: class Child1(Parent): __tablename__ = 'child1' __mapper_args__ = dict(polymorphic_identity = 'child1') child_id = Column(Integer, ForeignKey('parent.id'), primary_key=True) class Other(Base): __tablename__ = 'other' id = Column(Integer, primary_key=True) child1_id = Column(Integer, ForeignKey('child1.id')) child1_object = relation('Child1', backref='others', primaryjoin = child1_id == Child1.child_id) Bobby Impollonia wrote: > > I am porting some code from SQLA .48 to .53 . I have a relation that > works in .48, but not in .53. > > At the end of this post is a test program demonstrating the problem. > The program works in .48 but fails in .53 trying to understand the > child1_object relation . The error message says to add foreign_keys to > the relation, but that doesn't seem to actually help. > > It does however work if I change the relation to > child1_object = relation('Child1', backref='others', primaryjoin = > child1_id == Child1.__table__.c.id) > Is making this change the recommended solution? Is the behavior I am > seeing here expected? Is the message telling me to use foreign_keys > bogus? > > Here is the code: > > #!/usr/bin/python -u > from sqlalchemy import Column, Integer, create_engine, String, ForeignKey > from sqlalchemy.orm import sessionmaker, relation > from sqlalchemy.ext.declarative import declarative_base > > Base = declarative_base() > > class Parent(Base): > __tablename__ = 'parent' > id = Column(Integer, primary_key=True) > _cls = Column('cls', String(50)) > __mapper_args__ = dict(polymorphic_on = _cls ) > > class Child1(Parent): > __tablename__ = 'child1' > __mapper_args__ = dict(polymorphic_identity = 'child1') > id = Column(Integer, ForeignKey('parent.id'), primary_key=True) > > class Child2(Parent): > __tablename__ = 'child2' > __mapper_args__ = dict(polymorphic_identity = 'child2') > id = Column(Integer, ForeignKey('parent.id'), primary_key=True) > > class Other(Base): > __tablename__ = 'other' > id = Column(Integer, primary_key=True) > child1_id = Column(Integer, ForeignKey('child1.id')) > child1_object = relation('Child1', backref='others', primaryjoin = > child1_id == Child1.id) > > engine = create_engine('sqlite://') > Base.metadata.create_all(engine) > session = sessionmaker(engine)() > > def main(): > child1 = Child1() > child2 = Child2() > other = Other() > child1.others = [other] > session.add(child1) > session.add(child2) > session.add(other) > session.flush() > assert 2 == session.query(Parent).count() > assert child1 == session.query(Other).one().child1_object > > if __name__ == '__main__': > main() > > > > --~--~---------~--~----~------------~-------~--~----~ 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 sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---