从多对多关系查询sqlalchemy

querying from a many to many relationship sqlalchemy

我有这个数据库方案,多对多关系:

Base = declarative_base()

association_table = Table('association', Base.metadata,
    Column('book_id', Integer, ForeignKey('book.book_id')),
    Column('author_id', Integer, ForeignKey('author.author_id')),
)

class Book(Base):
    __tablename__ = 'book'
    book_id = Column(Integer, primary_key=True)
    title = Column(String(50), nullable = False)
    authors = relationship('Author', secondary = association_table, backref=backref('books', lazy= 'dynamic'))

class Author(Base):
    __tablename__ = 'author'
    author_id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable = False)

我想从哪里查询数据。我知道如何查询我创建的对象,例如:

a=Author(name='Author One')
b=Book(title='Book Title One')
session.add(b)
session.add(a)
session.commit() 
a.books.append(b)
session.commit()
# repeat above steps with new variables a2 and b2
# a.books.append(b2) 
for i in a.books:
   print(i.title)

但是,如何直接从 table 查询以查看与特定书籍相关的作者?即,下次我想使用数据库时,但不再有对象了。我尝试过的事情:

for u in session.query(Book.title).\
        filter(Book.book_id==Author.author_id).\
        filter(Author.name=='Author One').\
        all():
    print(u) # doesn't seem to work, returns only one element.

x = session.query(Author).filter(Book.title.any(name='Book Title One')).all()
# gives AttributeError: Neither 'AnnotatedColumn' object nor 'Comparator' object has an attribute 'any' error.

但他们似乎都失败了,或者return数量不正确。

您可以通过查询数据库在新会话中重新创建对象。例如,您可以获取作者

  author = session.query(Author).filter_by(name='Author One').one()

然后遍历他们的藏书:

  print('Author\'s books:')
  for b in author.books:
      print(b.title)

Author's books:
Book One
Book Three

或者使用 author 对象查询 Book 模型:

  query = session.query(Book).filter(Book.authors.contains(author))
  print('Books\' authors:')
  for b in query:
      print(b.title, ', '.join(a.name for a in b.authors))

Book's authors:
Book One Author One
Book Three Author Two, Author One

如果您不想获取作者对象,您可以使用作者姓名查询 Book 模型,如下所示:

  query = session.query(Book).filter(Book.authors.any(name='Author One'))
  print('Books by Author One:')
  for b in query:
      print(b.title, ', '.join(a.name for a in b.authors))

Books by Author One:
Book One Author One
Book Three Author Two, Author One