Flask通过模型关联有很多

时间:2019-03-01 02:42:00

标签: python sqlalchemy

Ruby on Rails具有“多次通过”关联。例如,

store has_many :shelves
shelf has many :books
store has_many :books, through: :shelves

这将使我们能够致电store.books并在商店中获得所有书籍。我想在Flask中复制此功能,但似乎找不到信息。

例如,这是用Python编写的一对多关系。店里有很多书架,书架上有很多书。

class Store(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    shelves = db.relationship('Shelf', backref='store')

class Shelf(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    location = db.Column(db.String(120), nullable=False)
    store_id = db.Column(db.Integer, db.ForeignKey('store.id'), nullable=False)
    books = db.relationship('Book', backref='shelf')

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    shelf_id = db.Column(db.Integer, db.ForeignKey('shelf.id'), nullable=False)    

使用当前编写的代码,我可以调用store.shelvesshelf.books。但是,要阅读书籍,我将不得不遍历书架并致电.books

是否可以在这里致电store.books

2 个答案:

答案 0 :(得分:1)

在架子上循环会非常低效。将其留给数据库引擎。

您需要创建一个自定义查询来实现。如果要使用store.books进行调用,可以在Store类中创建属性:

class Store(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    shelves = db.relationship('Shelf', backref='store')

    @property
    def books(self):
        query = Book.query.join(Shelf).join(Store).filter(Store.id == self.id)
        return query.all()

答案 1 :(得分:1)

一个选择是将Shelf用作“辅助”表并创建单边“多对多”关系,尽管实际上是一对表之间存在一对多关系:< / p>

class Store(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    shelves = db.relationship('Shelf', backref='store')
    books = db.relationship('Book', secondary='shelf', viewonly=True)

最好将这种关系仅视为视图,因为如果将其附加到Store.books列表中,则无法确定书籍应转到哪个书架。这与Rails定义关系的方式非常接近。