Sqlalchemy动态构建or_ conjunction和_

时间:2016-01-01 09:22:00

标签: python sqlalchemy

我尝试使用or_和and_生成动态连接但不生成SQL查询生成或。

每个查询的运算符or_和and_的数量各不相同。

查询:

echo "<input name='fred' value='{$row['test']}'>";

out sql:

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

最后我解决了这个问题,如果有更优雅的话,请分享一下:

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

1 个答案:

答案 0 :(得分:2)

您误解了or_and_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,只能合并为一个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%'), ) 。您的代码100%相当于:

    filter()

    AND的行为是AND每个条件。实际上,您的查询仅包含filter(and_(a, b, c, ...))

    请注意,filter(a, b, c, ...)相当于vagrant init hashicorp/precise32 vagrant up vagrant ssh