避免使用sqlalchemy查询在层次结构中加载特定的类



我想通过sqlalchemy查询加载实体,同时明确避免在我加载的实体的任何孩子的任何实例上加载特定类别的实体作为字段。采用以下数据模型:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
base = declarative_base()

class Parent(base):
    __tablename__ = 'Parent'
    uid = Column(Integer, primary_key=True)

class Child(base):
    __tablename__ = 'Child'
    uid = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('Parent.uid'))
    parent = relationship('Parent', backref="children")

class OtherChild(base):
    __tablename__ = 'OtherChild'
    uid = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('Parent.uid'))
    parent = relationship('Parent', backref="other_children")

class Bicycle(base):
    __tablename__ = 'Bicycle'
    uid = Column(Integer, primary_key=True)
    child_id = Column(Integer, ForeignKey('Child.uid'))
    child = relationship('Child', backref="bicycles")
    child_id = Column(Integer, ForeignKey('OtherChild.uid'))
    child = relationship('OtherChild', backref="bicycles")

如果我执行Parent.query.all(),那么我将分别恢复任何ChildOtherChild对象,这些对象分别在childrenother_children字段中。此外,我将获得嵌入在ChildOtherChild对象中的任何Bicycle对象。

我希望在Parent上进行CC_11,该CC_11明确避免在任何孩子中加载任何Bicycle对象,无论他们在数据结构中有多深。

更新:

可以使用options(contains_eager(<pathtoclass>))在查询中返回的孩子。例如(未经测试,但很确定它会起作用(:

query = query.outerjoin(Child, primaryjoin.expression).
    options(contains_eager('children'))

但是,这需要明确描述每条路径的options。在具有数百种有效选择的情况下,这变得繁重。我宁愿只表达诸如query.contains_eager(CLASS)

根据文档,关系默认使用懒惰加载。直到您直接访问关系属性为止,Bicycle不会加载。

由于该关系似乎是从BicycleChild以及从BicycleOtherChild的单向单向,因此您不必担心加载Bicycle对象,除非您专门查询它们。

最新更新