2015-02-02 10 views
6

Hi sqlalchemy eksperci tam, tutaj jest to trudne dla ciebie:SQLAlchemy zapytań filtr „kolumna jak każdy (array)”

Próbuję napisać kwerendę, która rozwiązuje się coś takiego:

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

użyciu 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) 

Wszelkie rozwiązania?

+0

Możliwy duplikat [Elixir/sqlalchemy odpowiednik SQL "LIKE" stwierdzeniem?] (Http://stackoverflow.com/questions/3325467/elixir-sqlalchemy-equivalent-to-sql-like-statement) – dshgna

Odpowiedz

13

Zastosowanie or_() i like() poniższy kod powinien zaspokoić potrzebę dobrze:

from sqlalchemy import or_ 

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

A, jeżeli stan WHERE my_column LIKE 'a%' OR my_column LIKE 'b%' będą generowane z góry kodu.

Jak, dlaczego Twój any() nie działa, myślę, że to dlatego, że wymaga to my_column się do listy (patrz here) i, na przykład, query(MyTable).filter(MyTable.my_list_column.any(name='abc')) jest powrót MyTable wierszy, jeśli każdy element w my_list_column kolumnie (lista) tego wiersza ma nazwę "abc", więc w rzeczywistości jest zupełnie inna niż twoja potrzeba.

+0

Dzięki za odpowiedź. Używanie or_() było innym rozwiązaniem, o którym myślałem, ale nie chciał tego, ponieważ może ono dość długo czekać. Ale chyba lepsze niż moje brudne rozwiązanie. – user1599438

+0

@ user1599438 Obawiam się, że musisz użyć 'lub _()' w tym przypadku, a to nie jest tak długo: p –

1

Można spróbować użyć any_()

W twoim przypadku będzie to wyglądać mniej więcej tak:

from sqlalchemy import any_ 

foo = ['a%', 'b%'] 
DBSession().query(MyTable).filter(MyTable.my_column.like(any_(foo))) 
Powiązane problemy