Cómo consultar SQLAlchemy de Many-To-Many

introduzca la descripción de la imagen aquí

Importar primero los módulos de Flask y SQLAlchemy :

 from flask import Flask from flask_sqlalchemy import SQLAlchemy 

Declara la app y los objetos db :

 app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///inquestion.db' db = SQLAlchemy(app) 

Hay tres tablas: Artist , Album y Genre . El objeto de Artist se puede vincular a varios Albums . Y el objeto del Album se puede vincular a varios Artists . La lista albums_to_artists_table es mantener la relación entre los Artists y los Albums ajustados:

 albums_to_artists_table = db.Table('albums_to_artists_table', db.Column('album_id', db.Integer, db.ForeignKey('album.id')), db.Column('artist_id', db.Integer, db.ForeignKey('artist.id'))) class Genre(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) class Album(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) genre_id = db.Column(db.Integer, db.ForeignKey('genre.id')) artists = db.relationship('Artist', backref='albums', lazy='dynamic', secondary=albums_to_artists_table) class Artist(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) _albums = db.relationship('Album', secondary=albums_to_artists_table, backref=db.backref('albums_to_artists_table_backref', lazy='dynamic')) 

Así que tenemos el Artist vinculado al Album que está vinculado al Genre y se ve así: Artist > Album > Genre .

Teniendo esta configuración en su lugar, seguimos adelante y creamos el objeto Genre primero:

 db.drop_all() db.create_all() genre = Genre(name='Heavy Metal') db.session.add(genre) db.session.commit() 

Luego dos álbumes:

 album1 = Album(name='Ride the Lightning', genre_id = genre.id) album2 = Album(name='Master of Puppets ', genre_id = genre.id) db.session.add(album1) db.session.add(album2) db.session.commit() 

Y el artista:

 artist = Artist(name='Metallica', _albums=[album1, album2]) db.session.add(artist) db.session.commit() 

Después de crear la base de datos, podemos consultar qué Albums están vinculados al Genre :

 print Album.query.filter_by(genre_id=1).all() 

y qué Artists están vinculados al Album :

 print Artist.query.filter(Artist._albums.any(id=album1.id)).all() 

Ahora me gustaría consultar a todos los Artists que están vinculados a un Genre pasa genre.id. ¿Cómo lograrlo?

Puede aplicar un filtro en Artist.albums.any() , que generará una subconsulta:

 Artist.query.filter(Artist.albums.any(genre_id=genre.id)).all() 

O puedes usar un join() en los álbumes:

 Artist.query.join(Artist.albums).filter_by(genre_id=genre.id).all()