我正在为我的宠物项目开发搜索功能。此功能建议用户输入一个或几个单词,搜索算法将解析所需的表,以便发现这些单词(或整个短语)是否存在于请求的列中。从技术上讲,使用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条款但你不知道你有多少项目,那么是否有更好的方法来解决这个问题?
答案 0 :(得分:1)
Python是一种动态语言,因此支持进行动态函数调用和属性访问。所以,你可以这样做:
or_(*(in_ == word for word in q.split()))
或者,或者,由于它是严格相等的,您可以使用IN
代替:
in_.in_(q.split())