Я пытаюсь сгенерировать динамическую конъюнкцию с or_ и and_, но SQL-запрос не генерирует or.

Количество операторов 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%')))

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

Antony Petrocelli

Ответов: 1

Ответы (1)

Вы неправильно понимаете использование or_, and_ и filter. Посмотрите в учебнике правильный пример.

Вы должны указать больше, чем одно предложение внутри 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%'),
    ),
)

По сути, вы использовали несколько фильтров с одним условием следующим образом:

  • Применение 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, ...).

  • .

2022 WebDevInsider