2015-06-15 3 views
2

У меня есть 2 таблицы, User и Object, которые имеют отношение «один ко многим» (a User могут иметь много objects).SQLAlchemy: filter by relationship

Как я могу фильтровать пользователей, имеющих хотя бы один объект, с помощью pep8-совместимого способа?

Этот код работает, но не pep8-совместимый:

query = session.query(User.id) 
query = query.filter(User.objects != None) 

В документации упоминается с помощью isnot: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#common-filter-operators

Но следующий код приводит к не реализованной ошибке.

query = session.query(User.id) 
query = query.filter(User.objects.isnot(None)) 
+0

use 'is not None' вместо'! = None' –

+1

Я уверен, что SQLAlchemy не работает с 'is not', хотя это допустимая конструкция Python. – bard

+0

ах ок. Я просто указал на очевидный не-PEP8. –

ответ

5

Как вы отметили, isnot не реализована для отношений, но только для простых колонн.

Что касается отношений, существует общая еще более мощная конструкция any(criterion, ...).

В вашем случае вы можете написать PEP8-совместимый код, приведенный ниже, который будет производить точно такой же SQL как в вашем вопросе:

q = session.query(User.id) 
q = q.filter(User.objects.any()) 

Но это также позволяет делать более сложные запросы, например: возвратные Пользователи, которые делают не есть объекты с value > 100:

q = session.query(User.id) 
q = q.filter(~User.objects.any(Object.value > 100)) 
0

Как вы знаете, в Django такой фильтрации с быть сделано в simple, declarative way:

Entry.objects.filter(blog__name='Beatles Blog') 

И я всегда мечтала иметь что-то подобное в SQLAlchemy.

Хорошие новости для вас: несколько недель назад я создал пакет для этого: https://github.com/absent1706/sqlalchemy-mixins#django-like-queries

Также пакет содержит очень полезные батареи: Active Record для SQLAlchemy, а также вложенную жадную загрузку и читаемый __repr__.