I want to load an entity via a sqlalchemy query while explicitly avoiding loading a specific class of entity as a field on any instance of any child of my loaded entity. Take the below data model:
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")
If I do a Parent.query.all() then I'm going to get back any Child or OtherChild objects which are in those Parent objects in the children and other_children fields, respectively. Further, I'll get any Bicycle objects which are embedded inside either the Child or OtherChild objects.
I wish to do a query on Parent which explicitly avoids loading any Bicycle objects on any children regardless how deep they may be in the data structure.
Update:
It is possible to constrain the children returned in a query using options(contains_eager(<pathtoclass>)). For example (not tested but pretty sure it would work):
query = query.outerjoin(Child, primaryjoin.expression).\
options(contains_eager('children'))
However, this requires explicitly describing the options for each path. In a circumstance with hundreds of valid options this becomes onerous. I would prefer to just express something like query.contains_eager(CLASS).