过滤多对多关系结果(烧瓶sqlalchemy)

时间:2019-08-18 16:18:18

标签: python flask-sqlalchemy

我有一个基本的多对多关系,如下所示,

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    user_favs  = relationship('Loop', secondary='active_association')

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


class Loop(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    creation_date = db.Column(db.DateTime())
    genre = db.Column(db.String())
    author = db.Column(db.Integer, db.ForeignKey('user.id'))


class Active_Association(db.Model):
    __tablename__ = 'active_association'
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id', ondelete='CASCADE'))
    loop_id = db.Column(db.Integer(), db.ForeignKey('loop.id', ondelete='CASCADE'))
    active = db.Column(db.Boolean(), default=False)

我正在这样添加user_favs:

loop = Loop.query.filter_by(id = request.form.get('loop')).first()
user = User.query.filter_by(id = request.form.get('user')).first()

user.user_favs.append(loop)
db.session.commit()

稍后,我将像这样检索所有user_favs:

user = User.query.filter_by(id = current_user.id).first()

loops = user.user_favs

这给了我一个包含所有user_favs的数组,但是我正在努力寻找一种按流派过滤它的方法。

我可以遍历它,但这似乎不是正确的解决方案。

我尝试了

user = User.query.filter_by(id = current_user.id).first()

loops = user.active_loops

filter(loops.genre == 'jazz')

但这给了我AttributeError:'AppenderQuery'对象没有属性'genre'

也许我把我的整个关系设置错了,如果设置正确,应该能够直接过滤掉它吗?这是我的第一个多对多关系,所以我在以下方面也可能走错了轨道:

active = db.Column(db.Boolean(), default=False)

原本打算用于其他功能,但我也不知道该如何解决。

1 个答案:

答案 0 :(得分:0)

您可以使用:lazy='dynamic',它将为您提供关系本身的BaseQuery。动态只是表示两个模型之间的联接类型。

class Loop(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    creation_date = db.Column(db.DateTime())
    genre = db.Column(db.String())
    author = db.Column(db.Integer, db.ForeignKey('user.id'))

    # will be .authors from Loop.authors
    authors = db.relationship(
        'User', 
        secondary=Active_Association, 
        backref=db.backref('loops'), # will be .loops on User
        lazy='dynamic'
    )

从本质上讲,它是查询中的查询,可最大程度地提高灵活性。

# gets the user
user = User.query.filter_by(id = current_user.id).first()

# this will return a collection of loops
loops = user.loops.filter_by(genre='jazz')

我一直试图在一个查询中管理该查询,而没有第二个查询,但是由于我的加入技巧对SQLAlchemy有点生疏,所以需要坐下来进行操作。