reinhardt
reinhardt

Reputation: 2253

How to make filtering on db in flask more efficient?

Flask beginner here

I have a flask app that stores data in a db. I am trying to filter the db based on the user parameters like country_code or price_type etc.

Right now, I have multiple filter functions in database.py as follows:

class DatabaseService:

    @staticmethod
    def read_list():
        items = Price.query.all()
        return {
            "items": items
        }

    @staticmethod
    def filter_prices_cc(country_code):
        if country_code is not None:
            items = Price.query.filter(country_code == country_code)
        return {
            "items": items
        }

    @staticmethod
    def filter_prices_pt(price_type):
        if price_type is not None:
            items = Price.query.filter(price_type == price_type)
        return {
            "items": items
        }

and I am calling these methods in controller.py as follows:

@ns.route("/")
class Prices(Resource):
    def get(self):
        country = request.args.get('country_code')
        price_type = request.args.get('price_type')
        if country is not None:
            return DatabaseService.filter_prices_cc(country)
        if price_type is not None:
            return DatabaseService.filter_prices_pt(price_type)
        else:
            return DatabaseService.read_list()

Is there a more efficient way to change the filter methods so that depending on what the request.args.get(), the db is filtered? Something like: defining one filter method in database.py and this takes the values from request.args.get() and filters the data

I have to get the following scenarios:

  1. If country_code is entered by the user, filter the db by it
  2. If price_type is entered by the user, filter the db by it
  3. If both price_type & country_code are entered by the user, filter the db by them combined
  4. If none of them are entered, then the entire list of values has to be shown

Sample data:

{
    "items": [
        {
            "id": 1,
            "value": 21.4,
            "start": "2020-05-12T00:00:00+02:00",
            "end": "2020-05-12T01:00:00+02:00",
            "country_code": "DE",
            "price_type": "DAY_AHEAD"
        },
        {
            "id": 2,
            "value": 18.93,
            "start": "2020-05-12T01:00:00+02:00",
            "end": "2020-05-12T02:00:00+02:00",
            "country_code": "DE",
            "price_type": "DAY_AHEAD"
        },
        {
            "id": 3,
            "value": 18.06,
            "start": "2020-05-12T02:00:00+02:00",
            "end": "2020-05-12T03:00:00+02:00",
            "country_code": "LU",
            "price_type": "DAY_AHEAD"
        },
        {
            "id": 4,
            "value": 17.05,
            "start": "2020-05-12T03:00:00+02:00",
            "end": "2020-05-12T04:00:00+02:00",
            "country_code": "DE",
            "price_type": "TODAY"
        }]}

Upvotes: 0

Views: 7118

Answers (1)

some_programmer
some_programmer

Reputation: 3528

I am not sure if this is the correct way, but you can pass the values from request.args.get() as **kwargs:

The database.py would look as:

class DatabaseService:
    @staticmethod
    def read_list(**filters):
        items = Price.query.filter_by(**filters).all()
        return {
            "items": items
        }

and controller.py as:

@ns.route("/")
class Prices(Resource):
    def get(self):
        country = request.args.get('country_code')
        price_type = request.args.get('price_type')
        return DatabaseService.read_list(**request.args)

Based on if you have the country_code or price_type, the filtering should work

This might be interesting for you:

flask sqlalchemy query with keyword as variable

Upvotes: 1

Related Questions