Sqlalchemy - an elegant way to deal with a few additional filters?

Suppose I have a request method with server-side additional filters. I want to achieve: if I pass some None value to filter the parameters, then make a filter, if the filter value is None, then just ignore it.

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

What I want to avoid is a template

 if XXX: res.filter(XXX=XXX) 

I wonder if there is an even more elegant way to achieve this?

For example, pass different filters as parameters?

Or maybe we can do the magic to lower the filter when the filter value is None?

+5
source share
1 answer

The code is completely equivalent to the one you showed:

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

I'm not quite sure why you need the named argument res.filter be specifically filter1 , filter2 , etc., but this snippet will do this without a repeating pattern that you, for obvious reasons, want to avoid.

If the names are not actually filter1 , filter2 , etc., this is normal as long as the required names are known:

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

This option will work in this case.

+3
source

Source: https://habr.com/ru/post/1210519/


All Articles