【问题标题】:SQLAlchemy Relationship Join with Multiple Foreign Keys具有多个外键的 SQLAlchemy 关系联接
【发布时间】:2015-06-19 14:37:25
【问题描述】:

使用 SQLAlchemy,我无法弄清楚如何映射以下关系:用户可以被其他用户“关注”,从而成为具有“关注者”的“领导者”。

class User( Base ):
    __tablename__ = 'users'
    id = Column( Integer, primary_key = True )
    followers = relationship( 'User', primaryjoin = 'and_( User.id == UserFollower.leader_id )', cascade = 'all' )
    leaders = relationship( 'User', primaryjoin = 'and_( User.id == UserFollower.follower_id )', cascade = 'all' )

class UserFollower( Base ):
    __tablename__ = 'users_followers'
    leader_id = Column( Integer, ForeignKey( 'users.id' ), primary_key = True )
    follower_id = Column( Integer, ForeignKey( 'users.id' ), primary_key = True )
    follower = relationship( 'User', uselist = False, foreign_keys = [ follower_id ] )
    leader = relationship( 'User', uselist = False, foreign_keys = [ leader_id ] )

从文档中我的印象是这样的声明会有

some_user.followers

在“users.id = users_followers.leader_id”上执行“users”和“users_followers”表的连接,其中“user.id = some_user.id”。

但是,这会产生错误(类似于How to specify table relationships in SQLAlchemy with multi-level/multiple joins?)。虽然建议的解决方案允许我解决这个问题,但它阻止了使用 SQLAlchemy 关系的“级联”属性,因此在删除用户时,相应的 UserFollower 对象也会被删除。

总而言之:如何将关系加入到具有多个外键引用同一个键的表中,并且仍然保留级联(删除)?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    如果您阅读 SQLAlchemy 文档的Self-Referential Many-to-Many Relationship 部分,您会意识到您有一个经典的多对多关系。如果您根据文档定义此关系,则级联将正常工作:

    users_followers = Table(
        'users_followers', Base.metadata,
        Column('leader_id', ForeignKey('users.id'), primary_key=True),
        Column('follower_id', ForeignKey('users.id'), primary_key=True),
    )
    
    
    class User(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        name = Column(String)
    
        followers = relationship(
            'User',
            secondary=users_followers,
            primaryjoin=id == users_followers.c.leader_id,
            secondaryjoin=id == users_followers.c.follower_id,
            backref="leaders",
            cascade='all',
        )
    

    【讨论】:

    • 确实是直接应用。我完全错过了。谢谢!
    猜你喜欢
    • 2017-08-23
    • 1970-01-01
    • 2021-07-10
    • 2019-10-16
    • 2020-12-30
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多