Python Peewee build queries dynamicly

30 Views Asked by At

I have some model like this:

class User(Model):
   username = CharField()
   email = CharField()
   disabled = BooleanField()
   admin = BooleandField()
   ...

and i want to write queries something like this:

def apply_filter(query, filter):
   match filter:
      case "disabled":
          return query.where(User.disabled == True)
      case "admin":
          return query.where(User.admin == True)
      case "protonmail":
          return query.where(User.email % "%protonmail.com")
...

def get_users(filters):
    results = []
    try:
        query = User.select()
        for filter in filters:
            query = apply_filter(query, filter);
        for e in query:
            results.append(e)

where additional filters are applied dynamicly

how could I achive this or something simmilar

Thanks for your help!

1

There are 1 best solutions below

1
coleifer On BEST ANSWER

The code you shared should work, as you're progressively adding additional filters to the query. Does it not work for some reason?

More generally, though, you can accumulate expressions in a list and then reduce them and pass them to .where():

def apply_filter(filter):
   match filter:
      case "disabled":
          return (User.disabled == True)
      case "admin":
          return (User.admin == True)
      case "protonmail":
          return (User.email % "%protonmail.com")
...

from functools import reduce
import operator

def get_users(filters):
    results = []
    query = User.select()
    exprs = [apply_filter(f) for f in filters]
 
    # AND expressions together:
    query = query.where(reduce(operator.and_, exprs))

    # OR expressions together:
    query = query.where(reduce(operator.or_, exprs))