FastAPI用户订阅模型SQLAlchemy关联关系报错求助
解决SQLAlchemy自关联订阅模型的ArgumentError异常
你碰到的这个sqlalchemy.exc.ArgumentError,是因为SQLAlchemy没法明确自关联关系里的本地/远程列对应关系——尤其是在借助secondary中间表实现用户订阅的场景下,你的配置存在两处问题:一是误用了remote_side参数,二是没有明确标记关联条件里的远程列。
修正后的代码
中间表(无需修改)
Subscription = Table( 'followers', Base.metadata, Column('author_id', Integer, ForeignKey('user.id'), primary_key=True), Column('follower_id', Integer, ForeignKey('user.id'), primary_key=True) )
User模型(两种可选写法)
写法1:移除多余的remote_side,调整关联条件
class User(SQLAlchemyBaseUserTable[int], Base): ... followings = relationship( 'User', secondary=Subscription, primaryjoin=(id == Subscription.c.follower_id), secondaryjoin=(Subscription.c.author_id == id), back_populates='followers', viewonly=True ) followers = relationship( 'User', secondary=Subscription, primaryjoin=(id == Subscription.c.author_id), secondaryjoin=(Subscription.c.follower_id == id), back_populates='followings', viewonly=True )
写法2:用remote()和foreign()明确标记远程列(更规范)
from sqlalchemy import remote, foreign class User(SQLAlchemyBaseUserTable[int], Base): ... followings = relationship( 'User', secondary=Subscription, primaryjoin=(id == foreign(Subscription.c.follower_id)), secondaryjoin=(remote(Subscription.c.author_id) == id), back_populates='followers', viewonly=True ) followers = relationship( 'User', secondary=Subscription, primaryjoin=(id == foreign(Subscription.c.author_id)), secondaryjoin=(remote(Subscription.c.follower_id) == id), back_populates='followings', viewonly=True )
关键说明
remote_side参数是给单表自关联(比如父节点-子节点结构)用的,不适用于secondary中间表的自关联场景,直接删掉就行。- 用
remote()标记中间表里属于远程用户的列,foreign()标记中间表里关联本地用户的列,能让SQLAlchemy清晰区分双方的关联逻辑,消除歧义。 - 逻辑对应关系:
followings:当前用户(follower)通过中间表的follower_id关联到author_id对应的用户,也就是当前用户关注的人。followers:当前用户(author)通过中间表的author_id关联到follower_id对应的用户,也就是关注当前用户的人。
内容的提问来源于stack exchange,提问作者Стас Затушевский
相关产品推荐
相关产品推荐

