sqlalchemy - 处理几个可选过滤器的优雅方式?

Xua*_* Hu 7 python mysql coding-style sqlalchemy

假设我有一个带有多个可选过滤器的查询方法.我想要实现的是,如果我传递一些非None值来过滤参数然后做一个过滤器,如果过滤值是None,那么就忽略它.

def get_query_results(filter1=None, filter2=None, ...):
    res = models.Item.query
    if filter1 is not None:
        res = res.filter(filter1=filter1)
    if filter2 is not None:
        res = res.filter(filter2=filter2)
    ....
    return res.all()
Run Code Online (Sandbox Code Playgroud)

我想避免的是模式

if XXX:
    res.filter(XXX=XXX)
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更优雅的方式来实现这一目标?

例如,将各种过滤器作为参数传递?

或者,当过滤器值为None时,我们可以做一些魔术来省略过滤器?

Ale*_*lli 5

代码完全等同于您展示的代码:

def get_query_results(*filters):
    res = models.Item.query
    for i, filt in enumerate(filters, 1):
        if filt is not None:
            d = {'filter{}'.format(i): filt}
            res = res.filter(**d)
    return res.all()
Run Code Online (Sandbox Code Playgroud)

我不明白为什么你需要指定的参数res.filter是专门filter1,filter2等等,但这个片段将做没有,你可以理解要避免重复模式.

如果该名称没有实际上filter1,filter2等等,只要所需的名字被称为是确定:

NAMES = 'foo bar baz bat'.split()

def get_query_results(*filters):
    res = models.Item.query
    for name, filt in zip(NAMES, filters):
        if filt is not None:
            d = {name: filt}
            res = res.filter(**d)
    return res.all()
Run Code Online (Sandbox Code Playgroud)

这种变体适用于这种情况.