sqlalchemy,选择使用反向包含(不在)子列值列表

时间:2013-11-18 23:57:46

标签: python sqlalchemy flask-sqlalchemy

我在flask-sqlalchemy中有一个典型的帖子/标签(许多标签与一个帖子相关联),我想选择未在我提供的列表中标记任何标签的帖子。首先,我建立的模型:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tags = db.relationship('Tag', lazy='dynamic')

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text(50))
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'))

这样的东西

db.session.query(Post).filter(Post.tags.name.notin_(['dont','want','these']))

失败

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Post.tags has an attribute 'name'

我假设是因为标签是关系而不是列。当我手动编写实际的SQL时,我在另一个项目上工作。这是有效的SQL:

SELECT * FROM $posts WHERE id NOT IN (SELECT post_id FROM $tags WHERE name IN ('dont','want','these'))

我如何使用sqlalchemy API实现这一目标?

4 个答案:

答案 0 :(得分:21)

使用否定的any非常简单:

query = session.query(Post).filter(~Post.tags.any(Tag.name.in_(['dont', 'want', 'these'])))

答案 1 :(得分:12)

试试这个,很简单:

users = session.query(Post).filter(not_(Post.tags.name.in_(['dont', 'want', these'])))

希望这有帮助!

答案 2 :(得分:4)

我想到了一个讨厌的解决方案,但它暂时有效。我很想知道是否有人想出更聪明的方法。

ignore_ids = [item.post_id for item in Tag.query.filter(Tag.name.in_(['dont','want','these'])).all()]
Post.query.filter(Post.id.notin_(ignore_ids))

答案 3 :(得分:0)

notin_对我有用,已调整示例

db.session.query(Post).filter(Post.tags.notin_(['dont','want','these']))