【问题标题】:How do you query a one-to-many relationship in an SQLAlchemy object instance?如何查询 SQLAlchemy 对象实例中的一对多关系?
【发布时间】:2015-08-14 18:46:21
【问题描述】:

假设我有以下(在 Python 3 和 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 Arabian Tale"
            return chapter
    return None

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

【问题讨论】:

  • 为什么不在Chapter 表中查询book.id?这只需要一个查询
  • 请注意,这是一个简化的案例:很可能启动第二个独立查询是获取此信息的最快/最佳方式。但是 a) 检查了原始对象是否存在各种安全问题,并且 b) 它可能已经在缓存中包含该信息,我不确定单独的查询是否必然会绕过原始对象的任何缓存。

标签: python python-3.x sqlalchemy


【解决方案1】:

如果您想获取特定书籍的特定章节,下面的代码应该在一条 SQL 语句中完成:

book = ...  # get book instance 

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

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

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

另请阅读Querying with JoinsSQLAlchemy Documentation 的其余部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 2011-09-26
    • 1970-01-01
    • 2019-01-18
    • 2012-09-17
    • 2013-09-19
    相关资源
    最近更新 更多