2015-02-02 2 views
6

эксперты Привет SQLAlchemy там, вот хитрая один для вас:SQLAlchemy фильтра запрос «колонок, как и любые (массив)»

Я пытаюсь написать запрос, который решает во что-то вроде:

SELECT * FROM MyTable where my_column LIKE ANY (array['a%', 'b%']) 

с помощью SQLAlchemy:

foo = ['a%', 'b%'] 

# this works, but is dirty and silly 
DBSession().query(MyTable).filter("my_column LIKE ANY (array[" + ", ".join(["'" + f + "'" for f in token.tree_filters]) + "])") 

# something like this should work (according to documentation), but doesn't (throws "AttributeError: Neither 'AnnotatedColumn' object nor 'Comparator' object has an attribute 'any'" 
DBSession().query(MyTable).filter(MyTable.my_column.any(foo, operator=operators.like) 

Любые решения?

+0

Возможный дубликат [Elixir/SQLAlchemy эквивалентном SQL "LIKE" заявление?] (HTTP://stackoverflow.com/questions/3325467/elixir-sqlalchemy-equivalent-to-sql-like-statement) – dshgna

ответ

13

Использование or_() и like(), следующий код должен удовлетворять ваши потребности хорошо:

from sqlalchemy import or_ 

foo = ['a%', 'b%'] 
DBSession().query(MyTable).filter(or_(*[MyTable.my_column.like(name) for name in foo])) 

А, где состояние WHERE my_column LIKE 'a%' OR my_column LIKE 'b%' будет генерироваться из выше коды.

А почему ваш any() не работал, я думаю, это потому, что она требует my_column быть список (см here), и, например, query(MyTable).filter(MyTable.my_list_column.any(name='abc')) является возвращение MyTable строки, если какой-либо элемент в my_list_column колонке (список) этой строки называется с 'abc', поэтому она на самом деле сильно отличается от вашей потребности.

+0

Спасибо за ответ. Использование or_() было другим решением, о котором я думал, но не хотел этого, потому что он может сделать запрос довольно длинным. Но все же лучше, чем мое грязное решение, я думаю. – user1599438

+0

@ user1599438 Боюсь, вам нужно использовать 'или _()' для этого случая, и на самом деле это не так долго: p –

1

Вы можете попробовать использовать any_()

В вашем случае это будет выглядеть примерно так:

from sqlalchemy import any_ 

foo = ['a%', 'b%'] 
DBSession().query(MyTable).filter(MyTable.my_column.like(any_(foo))) 
Смежные вопросы