2010-09-01 15 views
8

Soy nuevo en sqlalchemy y podría necesitar ayuda. Estoy tratando de escribir una pequeña aplicación para la cual tengo que cambiar dinámicamente una instrucción de selección. Entonces hago s = select([files]), y luego agrego filtros por s = s.where(files.c.createtime.between(val1, val2)). Esto funciona muy bien, pero solo con una conjunción AND. Entonces, cuando quiero tener todas las entradas con createtime (between 1.1.2009 and 1.2.2009) OR createtime == 5.2.2009, tengo el problema de que no sé cómo lograr esto con diferentes llamadas de filtro. Debido a la lógica de los programas no es posible utilizar s= s.where(_or(files.c.createtime.between(val1, val2), files.c.createtime == DateTime('2009-02-01')))Sqlalchemy: Produce la cláusula OR con filtro múltiple() - Llamadas

Gracias de antemano, Christof

Respuesta

26

Puede construir o cláusulas de forma dinámica a partir de listas:

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

pieza muy útil de código – Dimitris

+0

buen pedazo de code.Thanks :) – SRC

2

Si usted está dispuesto a "hacer trampa" haciendo uso del atributo _whereclause no documentado en los objetos Select, puede especificar de forma incremental una serie de términos O creando una nueva consulta cada vez en función de la cláusula where de la consulta anterior:

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

Crear una unión es otra opción. Esto es un poco clunkier, pero no se basa en atributos indocumentados:

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