如果事先不知道其内容,如何选择多行

时间:2017-09-08 20:42:15

标签: python sqlalchemy

我正在为我的宠物项目开发搜索功能。此功能建议用户输入一个或几个单词,搜索算法将解析所需的表,以便发现这些单词(或整个短语)是否存在于请求的列中。从技术上讲,使用SQL我可以用简单的OR条件来解决这个问题,但我想用sqlalchemy的容量来解决它。现有解决方案建议使用func.or_功能,但如果您事先知道一定数量的项目,它可以正常工作。所以这不是我的情况,因为我需要动态填充它们。因此,我完成了下一个解决方案:

def ext_search(q="", in_=None, div_id="", by=None, sort_asc=False, strict=True):
    """
    Searchs for the :q: in the database
    :param q: Search string
    :param in_: a class field from pp.models where a search will be performed
    :param div_id: ID of a division in which search will be performed
    :param by: a property of a class from pp.models that will be used
        for sorting
    :param sort_asc: defines sorting order
    :param strict: if search should be run for a phrase or words
    :return:
    """

    srt = asc if sort_asc is True else desc
    by = by if by else in_
    if strict:
        lq = [q]
    else:
        lq = q.split(' ')
    rv = db_session.query(in_.class_).filter(in_.class_.division_id == div_id)
    for i in range(len(lq)):
        lq[i] = u"{}.{} = '{}'".format(in_.class_.__tablename__, in_.key, lq[i])
    lqs = " OR ".join(lq)
    rv = rv.filter(text(lqs)).order_by(srt(by))
    if sort_asc:
        rv = rv.order_by(asc(by))
    else:
        rv = rv.order_by(desc(by))

    rv = rv.all()
    logger.debug("Found '{}' items for '{}' in '{}'.".format(len(rv), q, in_))
    return rv

我不喜欢的是我试图找出表格和列名称以及使用text()的方式,因为它违反了我的初始要求。所以我的问题是,如果你需要使用多个OR条款但你不知道你有多少项目,那么是否有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

Python是一种动态语言,因此支持进行动态函数调用和属性访问。所以,你可以这样做:

or_(*(in_ == word for word in q.split()))

或者,或者,由于它是严格相等的,您可以使用IN代替:

in_.in_(q.split())