Python 如何在SQLAlchemy中实现follow/followers关系

Python 如何在SQLAlchemy中实现follow/followers关系,python,sqlalchemy,Python,Sqlalchemy,以twitter为例。我们有一个User类,我们希望将用户定义为Follower和followerd。我们希望有这样一个方法u.followers,它返回跟随此用户u的用户列表。类似地,u.following应该返回一个用户列表,该用户u正在跟踪。这可以通过has MULTY THORT关系在RoR中实现,就像在中一样 我们如何在SQLAlchemy中做类似的事情呢?这里有一个简单的例子。它建立了一个数据库和一个具有自引用多对多关系的用户模型。最后,它展示了如何设置和获取用户的关注者和以下列表

以twitter为例。我们有一个
User
类,我们希望将用户定义为
Follower
followerd
。我们希望有这样一个方法
u.followers
,它返回跟随此用户
u
的用户列表。类似地,
u.following
应该返回一个用户列表,该用户
u
正在跟踪。这可以通过has MULTY THORT关系在RoR中实现,就像在中一样


我们如何在SQLAlchemy中做类似的事情呢?

这里有一个简单的例子。它建立了一个数据库和一个具有自引用多对多关系的用户模型。最后,它展示了如何设置和获取用户的关注者和以下列表

from sqlalchemy import create_engine, Column, Integer, String, Table, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, joinedload

engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base(bind=engine)

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    following = relationship(
        'User', lambda: user_following,
        primaryjoin=lambda: User.id == user_following.c.user_id,
        secondaryjoin=lambda: User.id == user_following.c.following_id,
        backref='followers'
    )

    def __str__(self):
        return self.name

    def __repr__(self):
        return '<User {0}>'.format(self)

user_following = Table(
    'user_following', Base.metadata,
    Column('user_id', Integer, ForeignKey(User.id), primary_key=True),
    Column('following_id', Integer, ForeignKey(User.id), primary_key=True)
)

Base.metadata.create_all()

u2 = User(name='jacob')
u3 = User(name='james')
u4 = User(name='victor')

u1 = User(name='david', followers=[u2, u3, u4])

session.add_all([u1, u2, u3, u4])
session.commit()

print u1.followers  # [<User jacob>, <User james>, <User victor>]
print u1.followers[0].following  # [<User david>]
从sqlalchemy导入创建引擎、列、整数、字符串、表、外键
从sqlalchemy.ext.declarative导入声明性基础
从sqlalchemy.orm导入sessionmaker、关系、joinedload
engine=create_engine('sqlite://:memory:',echo=True)
会话=会话生成器(绑定=引擎)
会话=会话()
Base=声明性_Base(bind=引擎)
类用户(基本):
__tablename_uu='user'
id=列(整数,主键=True)
名称=列(字符串,可空=False)
以下=关系(
“用户”,lambda:User\u如下所示,
primaryjoin=lambda:User.id==User\u following.c.User\u id,
secondaryjoin=lambda:User.id==User\u following.c.following\u id,
backref='followers'
)
定义(自我):
返回self.name
定义报告(自我):
返回“”。格式(自身)
用户\下表=表格(
“用户跟踪”,Base.metadata,
列('user\u id',Integer,ForeignKey(user.id),primary\u key=True),
列('following_id',Integer,ForeignKey(User.id),primary_key=True)
)
Base.metadata.create_all()
u2=用户(name='jacob')
u3=用户(name='james')
u4=用户(name='victor')
u1=User(name='david',followers=[u2,u3,u4])
session.add_all([u1,u2,u3,u4])
session.commit()
打印u1.followers#[,]
打印u1。跟随者[0]。跟随者#[]
SQLAlchemy的文档中也描述了这一点: