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