Python中Flask SQLAlchemy多对多关系如何进行多表查询?
Python Flask
我想要实现这样一个功能,即返回用户关注的所有标签下的所有问题,并按照问题时间顺序排序。
标签(Tag)与问题(Question)是多对多的关系,用户(User)与问题(Question)是一对多的关系
我之前直接用的 db.Table 实现多对多,现在按照狗书将关联表改成了一个 FollowTag 模型,联结查询一直不怎么理解,请问该如何实现这个功能?模型与查询怎么写?感谢!🙏
class FollowTag(db.Model):
tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'),
primary_key=True)
question_id = db.Column(db.Integer, db.ForeignKey('question.id'),
primary_key=True)
create_time = db.Column(db.DateTime, default=datetime.utcnow)
Python中Flask SQLAlchemy多对多关系如何进行多表查询?
FollowTag 表需要 user_id
在Flask-SQLAlchemy中,多对多关系的多表查询主要靠关系属性和连接查询来实现。假设我们有两个模型:User和Role,通过一个关联表user_roles建立多对多关系。
首先,定义模型和关系:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
# 关联表
user_roles = db.Table('user_roles',
db.Column('user_id', db.Integer, db.ForeignKey('users.id'), primary_key=True),
db.Column('role_id', db.Integer, db.ForeignKey('roles.id'), primary_key=True)
)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
roles = db.relationship('Role', secondary=user_roles, backref=db.backref('users', lazy='dynamic'))
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
查询方法:
- 通过关系属性直接查询:
# 查询用户的所有角色
user = User.query.get(1)
roles = user.roles # 直接访问关系属性
# 查询角色的所有用户
role = Role.query.get(1)
users = role.users.all()
- 使用join进行复杂查询:
# 查询拥有"admin"角色的所有用户
users = User.query.join(user_roles).join(Role).filter(Role.name == 'admin').all()
# 查询用户"john"的所有角色名
roles = Role.query.join(user_roles).join(User).filter(User.name == 'john').all()
- 多条件查询:
# 查询既是"admin"又是"editor"的用户
from sqlalchemy import and_
users = User.query.join(user_roles).join(Role).filter(
and_(Role.name == 'admin', Role.name == 'editor')
).all()
实际使用示例:
# 获取用户及其所有角色
user_with_roles = db.session.query(User, Role).\
join(user_roles).join(Role).\
filter(User.id == 1).all()
for user, role in user_with_roles:
print(f"User: {user.name}, Role: {role.name}")
关键点:
- 关系属性(
user.roles/role.users)提供了最直接的访问方式 - 对于复杂查询,使用
join()连接关联表和目标表 - 多条件查询时注意使用正确的连接逻辑
总结:多对多查询的核心是正确使用关系属性和join操作。
instances = db.session.query(Question).join( FollowTag, FollowTag.question_id=Question.id).join(Tag,Tag.id==FollowTag.tag_id).join(User,User.id==Tag.user_id).filter(User.id==查询用户 id)
…大学学得不好🤣,不知道这样有没有用
感谢,我已经解决了,这样就好了python<br>query = db.session.query(Question)<br>query = query.filter(Question.tags.any(Tag.users.any(<a target="_blank" href="http://User.id" rel="nofollow noopener">User.id</a> == <a target="_blank" href="http://self.id" rel="nofollow noopener">self.id</a>)))<br>

