使用多个外键连接 SQLAlchemy 关系

OnM*_*uck 3 python sqlalchemy

使用 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 ] )
Run Code Online (Sandbox Code Playgroud)

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

some_user.followers
Run Code Online (Sandbox Code Playgroud)

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

但是,这会产生错误(类似于如何在 SQLAlchemy 中使用多级/多连接指定表关系?)。尽管建议的解决方案允许我解决此问题,但它阻止了 SQLAlchemy 关系的“级联”属性的使用,因此在删除用户时,相应的 UserFollower 对象也会被删除。

总结:如何将关系连接到具有多个外键的表并仍然保留级联(删除)?

van*_*van 5

如果您阅读SQLAlchemy 文档的自引用多对多关系部分,您将意识到您有一个经典的多对多关系。如果您根据文档定义此关系,级联将正常工作:

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',
    )
Run Code Online (Sandbox Code Playgroud)