Zappa Django:它不是重新查询数据库,而是使用过时的内存缓存。这种行为可以改变吗?

Posted

技术标签:

【中文标题】Zappa Django:它不是重新查询数据库,而是使用过时的内存缓存。这种行为可以改变吗?【英文标题】:Zappa Django: instead of re-querying the database, it uses an outdated in-memory cache. Can this behavior be changed? 【发布时间】:2022-01-06 09:53:33 【问题描述】:

在我的项目中,我只使用 Django 作为前端。所有后端逻辑都是由状态机协调的几个 AWS Lambda Python 函数。数据库是 S3 存储桶中的 SQLite。我使用django_s3_storagedjango_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))
    

也没有用。

仅在 zappa-settings.json 中禁用周期性 keep_warm 事件会有所帮助。之后,如果没有调用,则在 10-15 分钟内释放服务器,过时的缓存消失。下次调用时,系统只好重新查询数据库,显示最近的数据。

有没有更好的解决方案?

【问题讨论】:

【参考方案1】:

您的 Django Lambda 容器实例将在加载时下载 SQLite DB,然后将文件缓存在本地,直到 Lambda 容器被 AWS 关闭。这是由django_s3_sqlite 包自动完成的。

由于您使用单独的后端系统写入数据库,因此 Django Lambda 容器实例不知道更改,因此不会从 S3 重新下载 SQLite DB。您列出的函数都是基于 Django 的缓存,不会产生任何影响。

如果您希望 Django 应用在更快的时间段内反映数据库更改,则需要迁移到集中式数据库,例如 RDS 上的 PostgreSQL 或 DynamoDB。

【讨论】:

以上是关于Zappa Django:它不是重新查询数据库,而是使用过时的内存缓存。这种行为可以改变吗?的主要内容,如果未能解决你的问题,请参考以下文章

尝试 OAuth 到 Twitter 时,无服务器 Django 应用程序(通过 Zappa 的 AWS Lambda)超时

Django如何获取0而不是null

即使数据库将 0 存储为字段值,Django 查询集对象也返回 None 而不是 0

Django 模板:有没有办法根据其属性查询特定对象(而不是遍历所有对象)?

使用 Django QuerySets 时使用列表推导而不是 for 循环

graphene-django:查询所有模型字段而不是请求的字段