Условная фильтрация в SQLAlchemy - PullRequest
1 голос
/ 21 сентября 2019

У меня есть этот монстр оператора if, который я использую для фильтрации результатов из базы данных, но он требует рефакторинга, есть ли способ сделать запросы фильтра условными для переменной?Мне нужно вернуть рецепт, относящийся к каждой категории / кухне, если он имеет идентификатор «1», который находится в моей БД.

if ingredients_form and any_ingredients == "1":
    if category_form == "1" and cuisine_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form))
            ).all()
    elif category_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)),
            Recipe.category_id==category_form
            ).all()
    elif cuisine_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)),
            Recipe.cuisine_id==cuisine_form
            ).all()
    else:
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)), 
            Recipe.category_id==category_form,
            Recipe.cuisine_id==cuisine_form
            ).all()

elif ingredients_form and any_ingredients == "2":
    if category_form == "1" and cuisine_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form))
            ).all()
    elif category_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)),
            Recipe.category_id==category_form
            ).all()
    elif cuisine_form == "1":
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)),
            Recipe.cuisine_id==cuisine_form
            ).all()
    else:
        search_result2 = Recipe.query.filter(
            Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
            ~Recipe._allergens.any(Allergen.id.in_(allergens_form)), 
            Recipe.category_id==category_form,
            Recipe.cuisine_id==cuisine_form
            ).all()

1 Ответ

0 голосов
/ 21 сентября 2019

Попробуйте:

import sqlalchemy

def custom_filter_statement(category_form, cuisine_form):
    if category_form == "1" and cuisine_form == "1":
        return sqlalchemy.sql.true()
    elif category_form == "1":
        return Recipe.category_id == category_form
    elif cuisine_form == "1":
        return Recipe.cuisine_id == cuisine_form
    return sqlalchemy.and_(Recipe.category_id==category_form, Recipe.cuisine_id==cuisine_form)

if ingredients_form and any_ingredients in ["1", "2"]:
    search_result2 = Recipe.query.filter(
        Recipe._ingredients.any(Ingredient.id.in_(ingredients_form)),
        ~Recipe._allergens.any(Allergen.id.in_(allergens_form)),
        custom_filter_statement(category_form, cuisine_form)
        ).all()

Я предлагаю переименовать переменные cuisine_form в kitchen_id и т. Д., Вызывать именование * _form для переменных, содержащих значение id, довольно обманчиво.

Также литералы "1" и"2" следует заменить константами с собственными описательными именами, чтобы сразу было понятно, что обозначают эти значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...