Search code examples
pythonpython-3.xpeewee

Python Peewee build queries dynamicly


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!


Solution

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