如何查询Many-To-Many SQLAlchemy

31

在此输入图片描述

首先导入FlaskSQLAlchemy模块:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

声明appdb对象:

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

有三张表:ArtistAlbumGenreArtist 对象可以链接到多个 Albums,而 Album 对象也可以链接到多个 Artists。为了保持 ArtistsAlbums 之间的关系紧密,需要使用 albums_to_artists_table 表格来维护它们之间的关系:

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

因此,我们将艺术家链接到专辑专辑链接到流派,看起来像这样:艺术家 > 专辑 > 流派

有了这个设置,我们首先创建流派对象:

db.drop_all()
db.create_all()

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

然后是两张专辑:

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

而艺术家:

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

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

数据库创建后,我们可以查询与 Genre 相关联的 Albums :

<code><code>print Album.query.filter_by(genre_id=1).all()
</code></code>

哪些艺术家专辑相关:

<code><code>print Artist.query.filter(Artist._albums.any(id=album1.id)).all()
</code></code>

现在我想查询所有与通过genre.id链接的Genre相关的Artists。如何实现?


嗯,你的关系似乎对我来说不太正确...根据你当前的关系,一个专辑只能有一个流派,这意味着一个艺术家要与x个流派相关联,他必须拥有x个专辑...这是你想要的吗? - danidee
是的,专辑和流派之间有一对一的关系是有意为之。 - alphanumeric
在上面的例子中,我该如何查询拥有超过1张专辑的艺术家? - Alexander Todorov
1个回答

34

您可以在Artist.albums.any()中应用筛选器,这将生成一个子查询:

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

或者你可以在 albums 上使用 join() 方法:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接