Почему данные, возвращаемые их кэша, не проходят валидацию?

Рейтинг: 1Ответов: 1Опубликовано: 13.05.2023

Пробую внедрить Redis для кеширования. Когда сервер пытается вернуть ответ из кеша, то выпадает следующая ошибка:

pydantic.error_wrappers.ValidationError: 1 validation error for Menu
response
  value is not a valid list (type=type_error.list)

Как я понимаю, при сравнивании с response_model что-то не сходится и поэтому возвращает ошибку.

Если из router.py удалить response_model=list[schemas.Menu], то ответ из кэша будет следующим:

"[{\"id\": \"fa3155d5-a4ff-44ca-89b0-c48ea14ec075\", \"submenus_count\": 1, \"description\": \"description1\", \"title\": \"title1\", \"dishes_count\": 1}]"

Получается, экранирующие слэши не дают правильно сравнить response_model, или проблема в неверном типе объекта, с которым хотят сравнить response_model.
Как мне избавиться от экранирующего слеша или как привести к правильному типу объекта?
Часть моего кода представлена ниже:

router.py:

@menu_router.get("", response_model=list[schemas.Menu])
def read_menus(menu_service: MenuService = Depends(get_menu_service)):
    return menu_service.get_menus()

service.py:

class MenuService:
    def __init__(self, menuDB: MenuDB, cache: Cache):
        self.menuDB = menuDB
        self.cache = cache

    def get_menus(self):
        menu_list = self.cache.get("menu_list:")

        if menu_list is None:
            menu_list = self.menuDB.get_menus()
            menu_str_list = json.dumps(jsonable_encoder(menu_list))
            self.cache.set("menu_list:", menu_str_list)
        return menu_list

cache.py:

class Cache:
    def __init__(self, cache):
        self.cache = cache

    def get(self, key):
        value = self.cache.get(name=key)
        if value:
            ola = json.loads(value)
            return value
        return None

    def set(self, key, value):
        json_value = json.dumps(jsonable_encoder(value))
        self.cache.set(name=key, value=json.dumps(json_value))

Ответы

▲ 0Принят

Все дело оказалось в неправильной установке зависимостей (Depends). Функция get_menus напрямую обращалась к Redis, минуя мой класс Cache, поэтому у меня не получалось ничего переопределить.

dependencies.py:

Было:

def get_menuDB(db: Session = Depends(get_db)):
    return MenuDB(db)

def get_menu_service(menuDB: MenuDB = Depends(get_menuDB),
                     cache: Cache = Depends(get_redis)):
    return MenuService(menuDB, cache)

Стало:

def get_menuDB(db: Session = Depends(get_db)):
    return MenuDB(db)

def get_cache(cashe = Depends(get_redis)):
    return Cache(cashe)

def get_menu_service(menuDB: MenuDB = Depends(get_menuDB),
                     cache: Cache = Depends(get_cache)):
    return MenuService(menuDB, cache)