2015-02-03 2 views
1

им писать проект с флягой и sqlalchemy.как определить sqlalchemy много для многих отношений

im пытается создать db, где у автора много книг.

для этой цели я писал:

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

первый вопрос: это правильный способ сделать это?

второй вопрос: я хочу знать, какие книги каждый автор написал - как я могу это сделать?

Третий вопрос: скажем, что каждая книга может быть написана множеством авторов, Как я могу узнать, какие авторы написали определенную книгу?

я заранее спасибо

+0

Если вы просто хотите, чтобы каждый автор, чтобы иметь много книг, вам нужно всего лишь от одного до многих отношений. Многим потребуется много, если каждая книга может иметь несколько авторов. –

+0

@BartoszMarcinkowski Я думаю, это именно то, о чем спрашивает OP в третьем вопросе: книги с несколькими авторами. –

ответ

2

Первый вопрос: это правильный способ сделать это?

Почти правильный. Вы также должны создать промежуточную модель, которая будет хранить фактические отношения. Поскольку это many-to-many relationship, для его работы требуется третья таблица.

второй вопрос: я хочу знать, какие книги каждый автор написал - как я могу это сделать?

Третий вопрос: скажем, что каждая книга может быть написана множеством авторов, как я могу узнать, какие авторы написали определенную книгу?

Вы можете легко достичь этого, используя SQLAlchemy's 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'>] 
+0

@brad, если вы используете Flask-SQLAlchemy, вы запускаете 'db.session.query' с моделью в качестве аргумента, как и в последнем кодеблоке; или прямо как 'Author.query.all()'. [Руководство пользователя Flask-SQLAlchemy] (https://pythonhosted.org/Flask-SQLAlchemy/queries.html#querying-records) охватывает его! –

Смежные вопросы