2015-02-02 6 views
6

Hallo SQLAlchemy Experten da draußen, hier ist eine knifflige Frage für Sie:SQLAlchemy Filterabfrage „Spalte LIKE ANY (Array)“

Ich versuche, eine Abfrage zu schreiben, die wie in etwas löst:

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

SQLAlchemy mit:

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) 

Irgendwelche Lösungen?

+0

Mögliche Duplikat [Elixir/SQLAlchemy entspricht SQL "LIKE" Anweisung?] (Http://stackoverflow.com/questions/3325467/elixir-sqlalchemy-equivalent-to-sql-like-statement) – dshgna

Antwort

13

Verwenden or_() und like(), der folgende Code soll Ihr Bedürfnis befriedigen gut:

from sqlalchemy import or_ 

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

A, in dem Zustand WHERE my_column LIKE 'a%' OR my_column LIKE 'b%' von oben Code erzeugt werden würde.

Was, warum Ihre any() funktionierten nicht, ich glaube, es ist, weil es my_column erfordert eine Liste zu sein (siehe here) und zum Beispiel query(MyTable).filter(MyTable.my_list_column.any(name='abc'))MyTable Zeilen zurückgeben, wenn jedes Element in my_list_column Spalt (eine Liste) dieser Zeile ist mit 'abc' benannt, also ist es eigentlich ganz anders als Ihr Bedürfnis.

+0

Danke für die Antwort. Die Verwendung von or_() war eine andere Lösung, an die ich gedacht habe, die ich aber nicht wollte, weil sie die Abfrage ziemlich lang machen kann. Aber immer noch besser als meine schmutzige Lösung, schätze ich. – user1599438

+0

@ user1599438 Ich fürchte, Sie müssen 'oder _()' für diesen Fall verwenden, und es ist tatsächlich nicht so lang: p –

1

Sie können versuchen, any_()

In Ihrem Fall zu verwenden, um es in etwa so aussehen würde:

from sqlalchemy import any_ 

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