2010-09-01 11 views
8

Je suis nouveau sur sqlalchemy et je pourrais avoir besoin d'aide. J'essaie d'écrire une petite application pour laquelle je dois modifier dynamiquement une instruction select. Donc, je fais s = select([files]), puis j'ajoute des filtres par s = s.where(files.c.createtime.between(val1, val2)). Cela fonctionne très bien, mais seulement avec une conjonction AND. Donc, quand je veux avoir toutes les entrées avec createtime (between 1.1.2009 and 1.2.2009) OR createtime == 5.2.2009, j'ai eu le problème que je ne sais pas comment y parvenir avec différents filtres-appels. En raison de la logique des programmes, il est impossible d'utiliser s= s.where(_or(files.c.createtime.between(val1, val2), files.c.createtime == DateTime('2009-02-01')))Sqlalchemy: Produire une clause OR avec plusieurs filtres() - Appels

Merci à l'avance, Christof

Répondre

26

Vous pouvez construire ou clauses dynamiquement des listes:

clauses = [] 
if cond1: 
    clauses.append(files.c.createtime.between(val1, val2)) 
if cond2: 
    clauses.append(files.c.createtime == DateTime('2009-02-01')) 
if clauses: 
    s = s.where(or_(*clauses)) 
+0

joli morceau pratique code – Dimitris

+0

beau morceau de code.Thanks :) – SRC

2

Si vous êtes prêt à « tricher » en utilisant l'attribut _whereclause non documenté sur les objets Select, vous pouvez spécifier de manière incrémentielle une série de termes OR en construisant une nouvelle requête chaque fois en fonction de la clause where de la requête précédente:

s = select([files]).where(literal(False)) # Start with an empty query. 
s = select(s.froms).where(or_(s._whereclause, 
     files.c.createtime.between(val1, val2))) 
s = select(s.froms).where(or_(s._whereclause, 
     files.c.createtime == datetime(2009, 2, 1))) 

Construire une union est une autre option. Ceci est un peu clunkier, mais ne repose pas sur des attributs non documentés:

s = select([files]).where(literal(False)) # Start with an empty query. 
s = s.select().union(
     select([files]).where(files.c.createtime.between(val1, val2))) 
s = s.select().union(
     select([files]).where(files.c.createtime == datetime(2009, 2, 1)))