django - 如何在 django 的模型管理器上动态交换默认数据库?
问题描述
我正在 django 和 django rest 框架中创建一个项目。它是一个角度应用程序的 api。数据库设置由多个数据库组成。一个是默认数据库,所有的 django 表都驻留在这个数据库中;其余的数据库属于一种用户类型,每个用户都应该有一个单独的数据库。因此,所有与用户相关的数据都进入其单独的数据库。为了动态实现选择数据库,用户对象有一个额外的字段来存储要写入的数据库。
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
"""Custom User model."""
database= models.CharField(max_length=9)
这样做的原因是提高了性能,因为每个数据库都是独立的,ListView 和 DetailView 的工作速度会比数据仅存储在一个数据库中更快。
我知道我可以使用模型管理器上的 using 方法来选择要存储的数据库。在其余的 api 中,一切正常,数据存储在各自的数据库中,但我最终覆盖了 django 定义的方法。它增加了项目的开发成本。外键和多对多键需要用用户的当前数据库来解析,因为我已经自定义了数据库设置,所以没有发生这种情况。此外,我的代码不如他们的 :p 好,因为他们多年来一直在编写 django。
我已经覆盖了很多查询集,但是 django 仍然多次使用默认数据库。如果我只能在 django 模型的模型管理器中使用请求对象来根据每个请求交换默认数据库,我认为情况会有所不同。
我的问题是——
有没有办法在模型管理器中访问请求对象?我可以做一些事情来影响下面的代码。
类 CustomManager(models.Manager):
def get_queryset(self, request): return super(CustomManager, self).using(request.user.database).get_queryset()
模型管理器具有可用于选择数据库的 _db 属性。会建议覆盖它吗?如果是,代码中的方式和位置?
- 有没有更好的方法来实现单独的数据库?
提前致谢。
问候
解决方案
在 Django 文档中建议使用数据库路由器,但问题是它只访问模型类。
发现了几个与动态切换数据库问题相关的问题。这篇文章有一个解决方案,可以解决使用实例request.user
传递或任何其他参数的问题。threading.local
有人甚至为此创建了一个可重用的插件 - https://github.com/ambitioninc/django-dynamic-db-router
希望有帮助。
推荐阅读
- javascript - 如何修复对象错误?数数还是数数反对?
- php - 连接失败:SQLSTATE[HY093]:参数号无效
- javascript - react mobx - 存储返回代理对象
- html - 如何使用角度 8 中的事件发射器将选定值从一个组件获取到另一个组件
- javascript - JavaScript 语句“z 的值是”+z+“。”我在理解这个输出时遇到了一些麻烦
- python - 如何在后台运行 Python 进程?
- javascript - 如何在 Vue 3.0 中通过 Webpack 使用 Bundler Build Feature Flags?
- javascript - 如何在 Jquery 3.4.1 和 Jquery-ui 1.12.1 中启用 CSP(内容安全策略)?
- python - 将不同的数据框列组合成新的数据框和奖励过滤问题
- python - 提取网格的幅度和频率(50 Hz +-2 Hz)和两个非常小的边带,正好是基波的 4/5 和 6/5