如何在Django的模型管理器上动态交换默认数据库?

时间:2019-02-26 12:42:55

标签: django django-rest-framework python-3.7

我正在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定义的方法。它增加了项目的开发成本。外键和ManytoMany键需要使用用户的当前数据库来解决,因为我已经定制了数据库设置,所以这没有发生。而且,我的代码不能像他们的:p一样好,因为他们多年来编写了django。

我已经覆盖了许多查询集,但是django仍然多次使用默认数据库。如果我只能使用django模型的模型管理器中的request对象在每个请求的基础上交换默认数据库,那我会有所不同。

我的问题是-

  1. 在模型管理器中是否可以访问请求对象?我可以做一些事情来影响下面的代码。

    CustomManager(models.Manager)类:

    def get_queryset(self, request):
    
        return super(CustomManager, self).using(request.user.database).get_queryset()
    
  2. 模型管理器具有_db属性,可用于选择数据库。建议覆盖它吗?如果是,代码中的位置和方式如何?

  3. 是否有更好的方法来实现单独的数据库?

先谢谢了。

致谢

1 个答案:

答案 0 :(得分:1)

Using a database router is recommended in Django docs,但问题在于它仅访问模型类。

找到了几个与动态切换数据库有关的问题。 This post has a solution可以解决传递request.user或任何其他参数by using a threading.local instance的问题。

有人为此创建了一个可重复使用的插件-https://github.com/ambitioninc/django-dynamic-db-router

希望有帮助。

相关问题