2016-01-01 4 views
1

Я пытаюсь создать динамическое соединение с or_ и and_, но не генерирует SQL-запрос или.Sqlalchemy динамически строить or_ conj и_

Число операторов or_ и and_ зависит от каждого запроса.

запрос:

q = se.query(Publicacion.update_time).join(Categoria).order_by(Publicacion.update_time.desc()) 
q = q.filter(and_(Publicacion.id_group_id == '103738479786979')) 
q = q.filter(and_(Publicacion.id_categoria_id == 1),) 
q = q.filter(and_(Categoria.estatus == True),) 
q = q.filter(or_(Publicacion.message.ilike('%Obsequios%')),) 
q = q.filter(or_(Publicacion.message.ilike('%jose%'))) 
q = q.filter(or_(Publicacion.message.ilike('%compu%'))) 

из SQL:

SELECT showgroups_publicacion.update_time AS showgroups_publicacion_update_time 
FROM showgroups_publicacion JOIN showgroups_categoria ON showgroups_categoria.id = showgroups_publicacion.id_categoria_id 
WHERE showgroups_publicacion.id_group_id = %(id_group_id_1)s AND showgroups_publicacion.id_categoria_id = %(id_categoria_id_1)s AND showgroups_categoria.estatus = true AND showgroups_publicacion.message ILIKE %(message_1)s AND showgroups_publicacion.message ILIKE %(message_2)s AND showgroups_publicacion.message ILIKE %(message_3)s ORDER BY showgroups_publicacion.update_time DESC 

В конце я решил так, если есть более элегантный, поделитесь им:

Y = and_ (column1 == 1) 
Y = and_ (column2 == 'SQL',Y) 

O = or_ (column1 == 2) 
O = or_ (column2 == 'Python',O) 

session.query(Model).filter(or_(O,Y)) 
+0

И каков ваш вопрос? –

ответ

2

Вы недопонимаете использование or_, and_ a d filter. Look at the tutorial for a correct example.

Вы должны указать больше, чем оговорку внутри and_or_), как и на всех языках программирования. Вместо того, чтобы писать это:

q = q.filter(and_(Publicacion.id_group_id == '103738479786979')) 
q = q.filter(and_(Publicacion.id_categoria_id == 1),) 
q = q.filter(and_(Categoria.estatus == True),) 

Вы должны быть написаны так:

q = q.filter(and_(
    Publicacion.id_group_id == '103738479786979', 
    Publicacion.id_categoria_id == 1, 
    Categoria.estatus == True, 
)) 

То же самое справедливо и для or_.

Теперь я не знаю, что вы имели в виду, поэтому я не могу рассказать вам, как в вашем случае должны быть объединены два предложения: and_ и or_. Возможно вы хотели бы сделать это:

q = q.filter(
    Publicacion.id_group_id == '103738479786979', 
    Publicacion.id_categoria_id == 1, 
    Categoria.estatus == True, 
    or_(
     Publicacion.message.ilike('%Obsequios%'), 
     Publicacion.message.ilike('%jose%'), 
     Publicacion.message.ilike('%compu%'), 
    ), 
) 

Что вы делали с помощью мультипликатор filter с одним условием статей, по сути это:

  • and_/or_ с одним условием является излишним, так что filter(and_(something)) эквивалентен filter(or_(something)), что эквивалентно filter(something).
  • Вы выдавали несколько filter, которые могут быть объединены только в один. Ваш код 100% эквивалентен:

    q = q.filter(
        Publicacion.id_group_id == '103738479786979', 
        Publicacion.id_categoria_id == 1, 
        Categoria.estatus == True, 
        Publicacion.message.ilike('%Obsequios%'), 
        Publicacion.message.ilike('%jose%'), 
        Publicacion.message.ilike('%compu%'), 
    ) 
    

    Поведение filter() является AND каждого состояния. Фактически, ваш запрос содержал только AND.

    Кстати, обратите внимание, что filter(and_(a, b, c, ...)) эквивалентен filter(a, b, c, ...).

+0

+1, спасибо Андреа, конечно, не понял, как использовать операторов, хотя решение, которое вы поднимаете для случая с фиксированными операторами, добавило динамическое решение, которое я нашел. –