【问题标题】:SQLAlchemy retrieve one-to-many entities by subquerySQLAlchemy 通过子查询检索一对多实体
【发布时间】:2013-08-19 07:54:21
【问题描述】:

如何指示 SQLAlchemy 加载一对多关系?我可以加入他们,但这会导致重复和(取决于结果的大小)大量开销。理想情况下,我想以某种方式修改session.query,以便发送多个(两个)查询以检索父母及其所有子实体。这如何通过配置 SQLA 或扩展会话类来实现?或者这可能不是 SQLA 中常用的处理方式...

【问题讨论】:

    标签: python sql join sqlalchemy one-to-many


    【解决方案1】:

    一对多的关系通常是通过在 Parent (,,one'') 类中创建一个 list 属性和在 Child (,,many'') 类中创建 parent_id 反向引用来完成的(请看这里:here)。

    所以你一般会创建 Parent 类:

    class Parent(Base):
      __tablename__ = "parents"
      dbid = Column(Integer, Sequence("parent_seq"), primary_key=True)
      children = relationship("Child", order_by = "Children.dbid", backref = "_parent")
    
      def __init__(self, children = [])
        self.children = children  #remember to initialize children as list!
    

    和子类:

    class Child(Base):
      __tablename__ = "children"
      dbid = Column(Integer, Sequence("child_seq"), primary_key=True)
      parent_dbid = Column(Integer, ForeignKey("parents.dbid"))
    

    如果您想将孩子添加到父母,只需这样做:

    p = Parent()
    c = Child()
    p.children.append(c)
    
    session.add(p)
    session.add(c)
    session.commit()
    

    然后,如果您想加载父级及其所有子级,您只需使用session.query(...) 加载父级,并且子级会自动加载-您不必进行任何联接,除非您愿意示例仅加载其孩子具有特定属性值的父母。

    希望对您有所帮助。如果有任何不清楚的地方,请写评论 - 我会尝试编辑我的答案以指定。

    【讨论】:

    • 感谢您的回复。 SQLA 将发送多少个查询来检索来自多个父级的所有子级?
    • 这取决于您的数据库结构以及您使用的数据库引擎。最简单的检查方法是启用打印 SQLA 进行的所有查询。您可以在创建引擎时执行此操作:engine = create_engine("path_to_your_database", echo = True)。然后像这样创建会话:Session = sessionmaker(bind = engine)session = Session ()。附言如果您喜欢我的回答,请接受它;)。
    • 默认情况下,SQLA 似乎正在查询每个父级的子级。可以通过将lazy 参数添加到关系字段来修改行为(请参阅docs.sqlalchemy.org/en/rel_0_7/orm/…)。
    猜你喜欢
    • 2012-12-18
    • 2013-07-13
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 2011-09-13
    • 1970-01-01
    相关资源
    最近更新 更多