sqlalchemy, seleccione usando una lista inclusiva inversa (no incluida) de valores de columnas secundarias

Tengo una relación típica de publicaciones / tags (muchas tags asociadas con una publicación) en flask-sqlalchemy, y quiero seleccionar publicaciones que no estén etiquetadas con ninguna etiqueta en la lista que proporciono. Primero, los modelos que configuro:

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')) 

Algo como

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

falla con

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

que asumo es porque las tags son una relación y no una columna. Tenía esto trabajando en otro proyecto cuando estaba escribiendo el SQL real manualmente. Este fue el SQL que funcionó:

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

¿Cómo lograría esto usando la API sqlalchemy?

Bastante sencillo usando any negado:

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

Prueba este, fácil:

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

¡Espero que esto ayude!

Pensé en una solución desagradable, pero funciona por el momento. Me interesaría saber si a alguien se le ocurre un método más inteligente.

 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))