SQLAlchemy multiple foreign keys in one mapped class to the same primary key

后端 未结 2 693
闹比i
闹比i 2020-11-29 00:52

Am trying to setup a postgresql table that has two foreign keys that point to the same primary key in another table.

When I run the script I get the error

相关标签:
2条回答
  • 2020-11-29 01:14

    The latest documentation:

    • http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html#handling-multiple-join-paths

    The form of foreign_keys= in the documentation produces a NameError, not sure how it is expected to work when the class hasn't been created yet. With some hacking I was able to succeed with this:

    company_id = Column(Integer, ForeignKey('company.id'), nullable=False)
    company = relationship("Company", foreign_keys='Stakeholder.company_id')
    
    stakeholder_id = Column(Integer, ForeignKey('company.id'), nullable=False)
    stakeholder = relationship("Company",
                                foreign_keys='Stakeholder.stakeholder_id')
    

    In other words:

    … foreign_keys='CurrentClass.thing_id')
    
    0 讨论(0)
  • 2020-11-29 01:29

    Tried removing quotes from the foreign_keys and making them a list. From official documentation on Relationship Configuration: Handling Multiple Join Paths

    Changed in version 0.8: relationship() can resolve ambiguity between foreign key targets on the basis of the foreign_keys argument alone; the primaryjoin argument is no longer needed in this situation.


    Self-contained code below works with sqlalchemy>=0.9:

    from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
    from sqlalchemy.orm import relationship, scoped_session, sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    engine = create_engine(u'sqlite:///:memory:', echo=True)
    session = scoped_session(sessionmaker(bind=engine))
    Base = declarative_base()
    
    #The business case here is that a company can be a stakeholder in another company.
    class Company(Base):
        __tablename__ = 'company'
        id = Column(Integer, primary_key=True)
        name = Column(String(50), nullable=False)
    
    class Stakeholder(Base):
        __tablename__ = 'stakeholder'
        id = Column(Integer, primary_key=True)
        company_id = Column(Integer, ForeignKey('company.id'), nullable=False)
        stakeholder_id = Column(Integer, ForeignKey('company.id'), nullable=False)
        company = relationship("Company", foreign_keys=[company_id])
        stakeholder = relationship("Company", foreign_keys=[stakeholder_id])
    
    Base.metadata.create_all(engine)
    
    # simple query test
    q1 = session.query(Company).all()
    q2 = session.query(Stakeholder).all()
    
    0 讨论(0)
提交回复
热议问题