我想通过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
对象中的所有Parent
或children
对象和other_children
字段。此外,我将获得Bicycle
或Child
对象中嵌入的所有OtherChild
对象。
我希望在query
上做一个Parent
,从而明确避免在任何子级上加载任何Bicycle
对象,无论它们在数据结构中有多深。
更新:
可以使用options(contains_eager(<pathtoclass>))
约束查询中返回的子级。例如(未经测试,但可以肯定会工作):
query = query.outerjoin(Child, primaryjoin.expression).\
options(contains_eager('children'))
但是,这需要为每个路径明确描述options
。在具有数百个有效选项的情况下,这变得很麻烦。我宁愿只表达类似query.contains_eager(CLASS)
的内容。
答案 0 :(得分:1)
根据the docs,关系默认情况下使用延迟加载。在您直接访问关系属性之前,不会加载Bicycle
个对象。
由于从Bicycle
到Child
以及从Bicycle
到OtherChild
似乎是单向的,所以您不必担心加载Bicycle
对象,除非您专门查询它们。