如何在SQLAlchemy中查询多级关系表中的特定子级



我有由外键链接的多级一对多表。

我经常根据family_id、祖父母和父母的名字来查询特定的孩子

查询结果应该只有一个。

如果一个子记录不存在,我将创建一个新的子记录并将其链接到给定的父记录。

  1. 子表的数目比父表的数目大得多。

    儿童>gt>gt;家长>gt;祖父母>系列

  2. 来自不同家庭的人可以有相同的名字。

    (子表中的名称可以相同,因为它们可能来自不同的家庭和不同的父母(

以下是的模型定义

class Families:
__tablename__ = 'families'
id = Column(Integer, primary_key=True)
family_name = Column(String, nullable=False)
grand_parents = relationship(GrandParents, backref="family")
class GrandParents:
__tablename__ = 'grand_parents'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
family_id = Column(Integer, ForeignKey("families.id"))
parents = relationship(Parents, backref="grand_parent")
class Parents:
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
grand_parent_id = Column(Integer, ForeignKey("grand_parents.id"))
childs = relationship(Childs, backref="parent")
class Childs:
__tablename__ = 'childs'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
parent_id = Column(Integer, ForeignKey("parents.id"))

现在,我使用join通过给定的family_id、祖父母的名字和父母的名字来查询目标子行

def get_child(family_id, grand_praent_name, parent_name, child_name):
child = session.query(Childs)
.join(Parents)
.join(GrandParents)
.filter(GrandParents.family_id == family_id,
GrandParents.name == grand_praent_name,
Parents.name == parent_name,
Childs.name == child_name).one_or_none()
return child

但每次,我都必须进行这种查询(遍历特定家族的所有子代,并根据业务逻辑更新它们的值(。

是否有更好的方法/设计/惯用方法来进行这种查询

如果只更新child,那么查询看起来不错。您可以考虑使用with_entities来避免获取许多不必要的数据:

def get_child(family_id, grand_praent_name, parent_name, child_name):
child = session.query(Childs)
.join(Parents)
.join(GrandParents)
.filter(GrandParents.family_id == family_id,
GrandParents.name == grand_praent_name,
Parents.name == parent_name,
Childs.name == child_name)
.with_entities(Childs).one_or_none()
return child

如果要同时更新parentgrandparent,则应使用joinedload以避免其他隐式查询。

如果您的查询遇到性能问题,您应该向外键添加索引以改进连接,例如:

parent_id = Column(Integer, ForeignKey("parents.id"), index=True)

最新更新