избегать загрузки определенного класса в иерархии с помощью запроса sqlalchemy - PullRequest
2 голосов
/ 25 июня 2019

Я хочу загрузить сущность с помощью запроса 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).

1 Ответ

1 голос
/ 25 июня 2019

Согласно документам , отношения используют ленивую загрузку по умолчанию.Bicycle объекты не будут загружаться, пока вы не получите прямой доступ к атрибуту отношения.

Поскольку отношения кажутся однонаправленными от Bicycle до Child и от Bicycle до OtherChild, вам не нужно беспокоиться о загрузке Bicycle объектов, если вы специально не запросите их,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...