#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, если хотите.