2015-02-02 14 views
6

esperti Hi SQLAlchemy là fuori, ecco un'ingannevole per voi:SQLAlchemy "colonna COME QUALSIASI (array)" query di filtro

Sto cercando di scrivere una query che si risolve in qualcosa di simile:

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

utilizzando 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) 

Eventuali soluzioni?

+0

Possibile duplicato [Elixir/SQLAlchemy equivalente a SQL "come" dichiarazione?] (Http://stackoverflow.com/questions/3325467/elixir-sqlalchemy-equivalent-to-sql-like-statement) – dshgna

risposta

13

Usa or_() e like(), il seguente codice dovrebbe soddisfare il vostro bisogno bene:

from sqlalchemy import or_ 

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

una condizione WHERE WHERE my_column LIKE 'a%' OR my_column LIKE 'b%' sarebbe generato dall'alto codice.

Per quanto riguarda il motivo per cui il any() non ha funzionato, penso che sia perché richiede my_column ad essere una lista (vedi here), e, per esempio, query(MyTable).filter(MyTable.my_list_column.any(name='abc')) è quello di tornare MyTable righe se un qualsiasi elemento in my_list_column colonna (una lista) di quella riga è chiamato con 'abc', quindi è in realtà molto diverso dal tuo bisogno.

+0

Grazie per la risposta. L'uso di or_() era un'altra soluzione a cui pensavo, ma non volevo ciò perché può rendere la query abbastanza lunga. Ma ancora meglio della mia soluzione sporca, immagino. – user1599438

+0

@ user1599438 Ho paura che tu debba usare 'o _()' per questo caso, e in realtà non è così lungo: p –

1

Si può provare a utilizzare any_()

Nel tuo caso sarebbe simile a questa:

from sqlalchemy import any_ 

foo = ['a%', 'b%'] 
DBSession().query(MyTable).filter(MyTable.my_column.like(any_(foo))) 
Problemi correlati