Как я могу остановить SQLAlchemy гидратации объекта ORM с результатами за пределами моего исходного запроса? - PullRequest
0 голосов
/ 09 апреля 2019

У меня проблемы с SQLAlchemy и Flask, которые корректно представляют данные моему API. В выводе содержится больше данных, чем в запросе ORM, поскольку SQLAlchemy лениво загружает отношения независимо от результата запроса.

Я собрал запрос, который выбирает Classification из Asset объектов, отфильтрованных подзапросом по внутреннему соединению для отношений на Assets / members / children этого Classification.

Я проверил SQL, созданный моим запросом ORM, и все это правильно и дает желаемые результаты. Однако, когда я запускаю код и проверяю выходные данные API, SQLAlchemy выбирает правильные Classification объекты, но затем представляет их со всеми Assets, а не отфильтрованными из исходного запроса, который я кропотливо построил.

Как уже упоминалось, это происходит из-за отложенной загрузки, различные стратегии загрузки, по-видимому, изменяют только то, как загружаются отношения, а не то, что загружается, и отключение отложенной загрузки приводит к тому, что он вообще не загружается.

Есть ли способ, которым я могу заполнить объекты ORM только данными из запроса, вместо того, чтобы позволить ему отключиться и заполнить все отношения независимо от того, что ??

# Inside Classification class
assets = db.relationship(
    'Asset',
    back_populates='classifications',
    secondary='class_object'
)

# Inside our repository package
query = (
    db.session.query(models.Classification)
)

assets_sub_query = (
    db.session.query(models.Asset)
    .join(models.Organisation, models.User.organisation)
    .join(models.Project, models.Organisation.projects)
    .join(models.Asset, models.Project.assets)
    .filter(models.User.id == user_id)
)

query = query.join(assets_sub_query.subquery(), models.Classification.assets)

Желаемый результат заключается в том, что Classification возвращается и отображается только с Assets из подзапроса, к которому мы присоединяемся.

SQLAlchemy фактически заполняет assets на основе исходного сопоставления отношений, поэтому он включает в себя все.

Должен быть способ сделать это, я смотрел на неосновные сопоставители, но не вижу, как в этом случае сопоставить ресурсы с запросом, а не со статической таблицей.

...