SQLAlchemy: фильтрация по многим, но возвращающая все результаты

Начиная с модели блога и тега «многие ко многим» и запроса из Querying отношения "многие ко многим" в SQLAlchemy, я знаю, что session.query(Blog).join(Blog.tags).options(contains_eager(Blog.tags)).filter(Blog.tags.in_(list_of_relevant_tags)).all() даст мне все сообщения блога, которые имеют хотя бы один из тегов в list_of_relevant_tags, и эти теги уже будут запрошены и возвращены.

Потенциальная проблема, которую я вижу (у меня проблемы с тестированием), заключается в том, что я хочу получить список тегов в возвращенных блогах. Я хочу вернуть все теги, но сгенерированный SQL предполагает, что в лучшем случае для этого потребуется второй запрос. В худшем случае SQLA вернет только те теги, которые соответствуют списку.

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


person Rus925    schedule 23.06.2014    source источник
comment
Я не думаю, что у вас есть проблема, которой вы боитесь. join и filter будут использовать совершенно разные объекты. Если вам неудобно, просто создайте тестовый пример для этого сценария.   -  person van    schedule 24.06.2014


Ответы (1)


Я кое-что понял. Однако это похоже на обходной путь; должен быть более прямой способ сделать это с помощью ORM.

По сути, вы используете подзапрос ассоциативной таблицы (назовем ее BlogTag со столбцами blog_id и tag_id, которые являются внешними ключами к blogs.id и tags.id соответственно) для создания списка blog_id, соответствующих критериям тега. Затем вы выполняете внутреннее соединение этого списка blog_id с неотфильтрованным запросом Blog, присоединенным к Tag, чтобы вернуть только соответствующие Blog.

t = session.query(BlogTag.blog_id).filter(BlogTag.tag_id.in_(list_of_relevant_tags)).\
    group_by(BlogTag.blog_id).subquery('t')
blogs = session.query(Blog).join(Blog.tags).join(t, t.c.blog_id == Blog.id).\
    options(contains_eager(Blog.tags)).all()
person Rus925    schedule 24.06.2014