如何查询SQLAlchemy对象实例中的一对多关系?

问题描述:

假设我有以下的(在Python 3和SQLAlchemy的):如何查询SQLAlchemy对象实例中的一对多关系?

class Book(Base): 
    id = Column(Integer, primary_key=True) 
    chapters = relationship("Chapter", backref="book") 

class Chapter(Base): 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    book_id = Column(Integer, ForeignKey(Book.id)) 

def check_for_chapter(book): 
    # This is where I want to check to see if the book has a specific chapter. 
    for chapter in book.chapters: 
     if chapter.name == "57th Ar* Tale" 
      return chapter 
    return None 

这感觉就像是“非习惯”的方法,因为它似乎不太可能利用数据库来搜索给定的一章。在最糟糕的情况下,看起来好像n调用db会检查章节标题,尽管我对SQLAlchemy的有限理解表明这可以在周围进行配置。我不知道的是,如果有一种方法可以直接针对您已经获取的对象的关系直接发起查询,如果是这样,那么怎么做呢?

+1

为什么不查询'book.id'的'Chapter'表?这将只需要一个查询 – goodcow

+0

请注意,这是一个简化的情况:可能很简单,启动第二个独立查询是此信息最快/最好的方式。但是a)原始对象被检查了各种安全问题,并且b)它可能已经将这些信息放入缓存中,并且我不确定是否单独的查询将必然绕过原始对象的任何缓存。 –

如果你想获得特定图书的特定章节,下面的代码应该这样做在一个SQL语句:

book = ... # get book instance 

chapter = (
    session.query(Chapter) 
    .with_parent(book) 
    .filter(Chapter.name == "57th Ar* Tale") 
    .one() 
) 

如果,例如,你只有书名和章节标题,你可以这样做:

chapter = (
    session.query(Chapter) 
    .join(Book) 
    .filter(Book.name == "One Thousand and One Nights") 
    .filter(Chapter.name == "57th Ar* Tale") 
    .one() 
) 

又看了Querying with JoinsSQLAlchemy Documentation休息。