On 7/20/15 10:49 AM, Douglas Russell wrote:

Apologies for cross-posting this, but I realised that this might be a better place to get an answer than this Stackoverflow question <http://stackoverflow.com/questions/31393824/polymorphic-self-referential-foreign-key-in-sqlalchemy> that I asked a week ago.

I am trying to resolve a problem with a self-referential table with Joined Table Inheritance where there is a foreign key linking the inheritance relationships, but then also a case where a class has an additional reference to an instance of its parent. Best to go with a simplified example:

Class B inherits from Class A. Class B is linked to Class A by the id column through the Foreign Key in Class B. Class B also has a column (|a_id|) which references Class A which has nothing to do with the inheritance.

|fromsqlalchemy importColumn,Integer,ForeignKey,create_engine fromsqlalchemy.ext.declarative importdeclarative_base fromsqlalchemy.orm importsessionmaker,relationship,backref Base=declarative_base()classA(Base):__tablename__ ='a'satype =Column(String(50))__mapper_args__ ={'polymorphic_identity':'a','polymorphic_on':satype }id =Column(Integer,primary_key=True)classB(A):__tablename__ ='b'id =Column(Integer,ForeignKey('a.id'),primary_key=True)__mapper_args__ ={'polymorphic_identity':'b'}a_id =Column(Integer,ForeignKey('a.id'))a =relationship('A',backref='b')engine =create_engine('sqlite:///:memory:',echo=True)Base.metadata.create_all(engine)Session=sessionmaker(bind=engine)session =Session()|

As per the documentation <http://docs.sqlalchemy.org/en/latest/orm/relationship_persistence.html#rows-that-point-to-themselves-mutually-dependent-rows>, I would resolve the case where there are multiple ForeignKeys between tables by explicitly specifying in the relationship which was to be used.


the "mutually dependent foreign keys" document doesn't really apply to this case. What happens here is that B(A) requires a join from B to A, and then B.a requires a different one. Even though the conventions here make it clear which foreign key constraint is which, the mapper still needs them to be explicitly spelled out, that's like this:

class B(A):
    __tablename__ = 'b'

    id = Column(Integer, ForeignKey('a.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'b',
        'inherit_condition': id == A.id
    }

    a_id = Column(Integer, ForeignKey('a.id'))
    a = relationship(
        'A',
        backref='b', primaryjoin=A.id == a_id, remote_side=A.id)






|classB(A):__tablename__ ='b'id =Column(Integer,ForeignKey('a.id'),primary_key=True)__mapper_args__ ={'polymorphic_identity':'b'}a_id =Column(Integer,ForeignKey('a.id'))# I know the primaryjoin is no longer needed in SA >= 0.8a =relationship('A',backref='b',foreign_keys=[a_id],primaryjoin=a_id==A.id)|

I think the problem is that I don't seem to be able to figure out how to do the same for the polymorphic column |id| as I am not explicitly defining that relationship.

Cheers,

Douglas


--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com <mailto:sqlalchemy+unsubscr...@googlegroups.com>. To post to this group, send email to sqlalchemy@googlegroups.com <mailto:sqlalchemy@googlegroups.com>.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to