web-dev-qa-db-fra.com

Comment interroger plusieurs à plusieurs SQLAlchemy

enter image description here

Importez d'abord les modules Flask et SQLAlchemy:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

Déclarez les objets app et db:

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

Il existe trois tables: Artist, Album et Genre. L'objet Artist peut être lié à plusieurs Albums. Et l'objet Album peut être lié à plusieurs Artists. Le albums_to_artists_table est de maintenir la relation entre Artists et Albums:

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

Nous avons donc le Artist lié au Album qui est lié à Genre et il ressemble à ceci: Artist> Album> Genre.

Une fois cette configuration en place, nous allons de l'avant et créons d'abord l'objet Genre:

db.drop_all()
db.create_all()

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

Puis deux albums:

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

Et l'artiste:

artist = Artist(name='Metallica',  _albums=[album1, album2])

db.session.add(artist)
db.session.commit()

Une fois la base de données créée, nous pouvons demander à quels Albums sont liés à Genre:

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

et ce que Artists sont liés à Album:

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

Maintenant, je voudrais interroger tous les Artists qui sont liés à un Genre passant le genre.id. Comment y parvenir?

15
alphanumeric

Vous pouvez appliquer un filtre dans Artist.albums.any(), ce qui générera une sous-requête:

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

Ou vous pouvez utiliser une join() sur les albums:

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