【问题标题】:how to define a sqlalchemy many to many relationship如何定义 sqlalchemy 多对多关系
【发布时间】:2015-04-02 19:49:45
【问题描述】:

我正在用烧瓶和 sqlalchemy 编写一个项目。

我正在尝试创建一个数据库,其中 Author 拥有许多书籍。

为此我写道:

class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name= db.Column(db.String(80))


class Books(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    author = db.Column(db.Integer, db.ForeignKey('author.id'))

第一个问题:这样做的方法是否正确?

第二个问题:我想知道每个作者写了哪些书——我该怎么做?

第三个问题:假设每本书可以由很多作者写, 我怎么知道哪位作者写了某本书?

提前致谢

【问题讨论】:

  • 如果你只是想让每个作者有很多书,你只需要一对多的关系。如果每本书也可以有多个作者,则需要多对多。
  • @BartoszMarcinkowski 我认为这正是 OP 在第三个问题中提出的问题:多作者的书籍。

标签: flask sqlalchemy flask-sqlalchemy


【解决方案1】:

第一个问题:这样做的方法是否正确?

几乎正确。您还应该创建一个中间模型来存储实际关系。由于是many-to-many relationship,所以需要第三张表才能操作。

第二个问题:我想知道每个作者写了哪些书——我该怎么做?

第三个问题:假设每本书可以由很多作者写,我怎么知道哪位作者写了某本书?

您可以使用 SQLAlchemy 的association proxy 轻松实现它。

类似的东西:

from myapp import db

from sqlalchemy.ext.associationproxy import association_proxy


class Book(db.Model):
    __tablename__ = 'book'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(60))

    # access all authors of that book
    authors = association_proxy('bookauthor', 'author', creator=lambda author: BookAuthor(author=author))

    def __init__(self, title):
        self.title = title

    def __unicode__(self):
        return '<Book {0}>'.format(self.id)


class Author(db.Model):
    __tablename__ = 'author'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))

    # access all books w/ this author
    books = association_proxy('bookauthor', 'book', creator=lambda book: BookAuthor(book=book))

    def __init__(self, name):
        self.name = name

    def __unicode__(self):
        return '<Author {0}>'.format(self.id)


class BookAuthor(db.Model):
    """ This is an association table for the Book<->Author Many to Many relationship. """
    __tablename__ = 'book_author'

    id = db.Column(db.Integer, primary_key=True)

    id_book = db.Column(db.Integer, db.ForeignKey('book.id'), primary_key=True)
    id_author = db.Column(db.Integer, db.ForeignKey('author.id'), primary_key=True)

    # you can also access these objects of books and authors respectively
    book = db.relationship(Book, backref='bookauthor')
    author = db.relationship(Author, backref='bookauthor')

    def __unicode__(self):
        return '<BookAuthor {0}>'.format(self.id)

这样您就可以使用以下方式访问本书的所有作者:

book = db.session.query(Book).filter_by(title="The Catcher in the Rye")
book.authors()
# [<Author 'J. D. Salinger'>]

【讨论】:

  • @brad 如果您使用 Flask-SQLAlchemy,您可以使用模型作为参数运行 db.session.query,就像我在后一个代码块中所做的那样;或直接点赞Author.query.all()Flask-SQLAlchemy's manual 已经覆盖了!
猜你喜欢
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
  • 2021-06-26
  • 2019-06-22
  • 2016-08-06
相关资源
最近更新 更多