Zappa Django: вместо повторного запроса к базе данных используется устаревший кэш в памяти. Можно ли изменить это поведение?
В моем проекте я использую Django только в качестве фронтенда. Вся логика бэкенда - это несколько Python-функций AWS Lambda, координируемых государственной машиной. База данных - SQLite в ведре S3. Я использую django_s3_storage
и django_s3_sqlite
. Мои функции бэкенда изменяют количество экземпляров модели и их детали в базе данных SQLite. Я бы хотел, чтобы эти изменения были отражены фронтендом Django как можно скорее. Однако этого не происходит. Я вижу только устаревший кэш в памяти
Я пробовал несколько способов.
Мой первоначальный взгляд:
class AllPortfolioRowsView(ListView):
model = PortfolioRow
template_name = "portfolio_all_rows.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# do something else
context['object_list'] = PortfolioRow.objects.all().order_by('row_type')
return context
Я прочитал совет делать что-то внутри функции get. В этом случае, якобы, при каждом вызове функции должен выполняться запрос к базе данных.
Вариант №2:
class AllPortfolioRowsView(View):
def get(self, request):
template = loader.get_template('portfolio_all_rows.html')
object_list = PortfolioRow.objects.all().order_by('row_type')
# do something else
context = {
'object_list': object_list,
# other stuff
}
return HttpResponse(template.render(context, request))
Это сработало, но не помогло.
Затем я попытался принудительно запросить базу данных, как рекомендуется в документации Django.
Вариант №3:
class AllPortfolioRowsView(View):
def get(self, request):
template = loader.get_template('portfolio_all_rows.html')
object_list = PortfolioRow.objects.all().order_by('row_type')
for elem in object_list: # iteration
counter = counter + 1
print(counter, ' - ', elem)
_ = list(object_list) # create list to force re-evaluation
# do something else
context = {
'object_list': object_list,
# other stuff
}
return HttpResponse(template.render(context, request))
Это тоже не помогло.
Помогло только отключение периодического события keep_warm
в zappa-settings.json
. После этого, если нет обращений, сервер освобождается через 10-15 минут, и устаревший кэш исчезает. При следующем обращении системе ничего не остается, как заново запросить базу данных и отобразить свежие данные.
Есть ли лучшее решение?
Ваши экземпляры контейнера Django Lambda будут загружать SQLite DB при загрузке, а затем будут кэшировать файл локально, пока контейнер Lambda не будет выключен AWS. Это делается автоматически с помощью пакета django_s3_sqlite
.
Поскольку вы делаете записи в базу данных, используя отдельную бэкенд-систему, экземпляры контейнера Django Lambda не знают об изменениях и поэтому не будут повторно загружать SQLite DB с S3. Все функции, которые вы перечислили, являются кэшированием на основе Django и не будут иметь никакого эффекта.
Если вы хотите, чтобы приложение Django отражало изменения в БД в более быстрый период времени, вам необходимо перейти на централизованную базу данных, такую как PostgreSQL на RDS или DynamoDB.