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

时间:2019-06-24 23:41:28

标签: python 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(),那么我将取回Child中那些OtherChild对象中的所有Parentchildren对象和other_children字段。此外,我将获得BicycleChild对象中嵌入的所有OtherChild对象。

我希望在query上做一个Parent,从而明确避免在任何子级上加载任何Bicycle对象,无论它们在数据结构中有多深。

更新

可以使用options(contains_eager(<pathtoclass>))约束查询中返回的子级。例如(未经测试,但可以肯定会工作):

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

但是,这需要为每个路径明确描述options。在具有数百个有效选项的情况下,这变得很麻烦。我宁愿只表达类似query.contains_eager(CLASS)的内容。

1 个答案:

答案 0 :(得分:1)

根据the docs,关系默认情况下使用延迟加载。在您直接访问关系属性之前,不会加载Bicycle个对象。

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