2010-09-01 1 views
8

Ich bin neu zu sqlalchemy und könnte etwas Hilfe verwenden. Ich versuche, eine kleine Anwendung zu schreiben, für die ich eine Select-Anweisung dynamisch ändern muss. Also mache ich s = select([files]), und dann füge ich Filter durch s = s.where(files.c.createtime.between(val1, val2)) hinzu. Das funktioniert super, aber nur mit einer UND-Konjunktion. Also, wenn ich alle Einträge mit createtime (between 1.1.2009 and 1.2.2009) OR createtime == 5.2.2009 haben möchte, habe ich das Problem, dass ich nicht weiß, wie man das mit verschiedenen Filter-Calls erreicht. Wegen der Programme Logik möglich, es ist nicht s= s.where(_or(files.c.createtime.between(val1, val2), files.c.createtime == DateTime('2009-02-01')))Sqlalchemy: OR-Klausel mit mehreren Filter() - Aufrufe

Vielen Dank im Voraus zu verwenden, Christof

Antwort

26

können Sie bauen oder Klauseln dynamisch von Listen:

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

ziemlich praktisch Stück Code – Dimitris

+0

schönes Stück code.Thanks :) – SRC

2

Wenn Sie bereit sind zu „betrügen“ Wenn Sie das undokumentierte _whereclause-Attribut für Select-Objekte verwenden, können Sie schrittweise eine Reihe von OR-Termen angeben, indem Sie basierend auf der WHERE-Klausel der vorherigen Abfrage eine neue Abfrage erstellen:

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

Der Aufbau einer Union ist eine weitere Option. Das ist ein bisschen clunkier, aber beruht nicht auf undokumentierte Attribute:

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