以twitter为例。我们有一个User
类,我们想要将用户定义为Follower
和Followed
。我们希望有一个类似u.followers
的方法,它返回一个列表跟随此用户u
的用户。同样,u.following
应返回用户列表,此用户u
正在关注。这可以通过has-many-through关系在RoR中实现,如this article中所示。
我们如何在SQLAlchemy中执行类似的操作?
答案 0 :(得分:5)
这是一个极小的例子。它建立了一个具有自引用多对多关系的数据库和用户模型。最后,它展示了如何设置和获取用户的关注者以及以下列表。
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的文档中也对此进行了描述:Self-Referential Many-to-Many Relationship