Неизвестная ошибка при извлечении объектов набора запросов django из redis

#python #django #django-models #redis

Вопрос:

В приведенном ниже фрагменте кода я пытаюсь вывести кэшированные объекты из redis, при этом сталкиваясь с приведенной ниже ошибкой.

Вариант использования-кэширование 30 лучших объектов комментариев при 1-м вызове API , поэтому, когда API вызывается 2-й раз , кэшированные объекты будут переданы сериализаторам, избегая наборов запросов.

Кэширование объектов комментариев.

 featured=StockUserComments.objects.filter(some condition)
qs=StockUserComments.objects.filter(some condition)
latest=StockUserComments.objects.filter(some condition)

all =list(chain(featured,qs,latest))

redis_client.set("feeds:top_comments", str(all[:30]),ex=1800)
 

извлечение объектов

 top_comments = redis_client.get("feeds:top_comments")
if top_comments:
  print("from cache")
  all = ast.literal_eval(top_comments.decode("utf-8"))
 

ошибка

 Traceback (most recent call last):
  File "E:stocktalk-api-platformvenvlibsite-packagesdjangocorehandlersexception.py", line 34, in inner
    response = get_response(request)
  File "E:stocktalk-api-platformvenvlibsite-packagesdjangocorehandlersbase.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "E:stocktalk-api-platformvenvlibsite-packagesdjangocorehandlersbase.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:stocktalk-api-platformvenvlibsite-packagesdjangoviewsdecoratorscsrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "E:stocktalk-api-platformvenvlibsite-packagesdjangoviewsgenericbase.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "E:stocktalk-api-platformvenvlibsite-packagesrest_frameworkviews.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "E:stocktalk-api-platformvenvlibsite-packagesrest_frameworkviews.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "E:stocktalk-api-platformvenvlibsite-packagesrest_frameworkviews.py", line 476, in raise_uncaught_exception
    raise exc
  File "E:stocktalk-api-platformvenvlibsite-packagesrest_frameworkviews.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "E:stocktalk-api-platformappsstock_dashboardviews.py", line 748, in get
    all = ast.literal_eval(top_comments.decode("utf-8"))
  File "C:UsersFleetstudioAppDataLocalProgramsPythonPython38libast.py", line 59, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "C:UsersFleetstudioAppDataLocalProgramsPythonPython38libast.py", line 47, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 1
    [<StockUserComments: Cm>, <StockUserComments: R3>, <StockUserComments: Re>, <StockUserComments: N5>, <StockUserComments: New1>, <StockUserComments: R1>, <StockUserComments: Cm>, <StockU
serComments: New2>, <StockUserComments: ~EMPTY_COMMENT>, <StockUserComments: ~EMPTY_COMMENT>, <StockUserComments: I think it’s time to sell here>, <StockUserComments: ~EMPTY_COMMENT>, <Stoc
kUserComments: ~EMPTY_COMMENT>, <StockUserComments: ~EMPTY_COMMENT>, <StockUserComments: Time to sell indeed>, <StockUserComments: Time to sell.>, <StockUserComments: What a great company
 huge opportunities ahead. I would definitely be a buyer here. Although this is a risky one lots of volatility be careful
     ^
SyntaxError: invalid syntax
 

Комментарии:

1. Вам не нужно использовать ast.literal_eval . Вы сериализовали свои объекты в redis_client ?

2. нет, просто объекты были отправлены в редис

3. Попробуйте посмотреть, какой тип вывода у вас есть без ast.literal_eval

4. в нем есть только числа без ast.literal_val

Ответ №1:

Один из подходов к сериализации ваших объектов (помимо использования str и ast.literal_eval , что на самом деле не сработает) заключается в использовании pickle :

 import pickle
redis_client.set("feeds:top_comments", pickle.dumps(all[:30]), ex=1800)
 

Это приведет к сериализации вашего набора запросов в виде байтов, которые могут быть извлечены обратно в виде набора запросов. Затем вы можете извлечь с помощью:

 import pickle
top_comments = redis_client.get("feeds:top_comments")
all = pickle.loads(top_comments)
 

Обратите внимание, что набор запросов, который вы получаете, pickle.loads может быть устаревшим по сравнению с тем, что у вас есть в базе данных. В этом случае вы можете сериализовать, используя вместо этого идентификаторы объектов, и просто получить их снова. Обратите внимание, что вы также можете использовать другие виды сериализации, такие как json, если хотите.