Django - 如何为模型指定数据库?

问题描述 投票:22回答:3

有没有办法指定模型(或应用程序,甚至)应该只使用一个特定的数据库?

我正在使用一个我不想改变的遗留数据库。我有两个数据库 - 'default'是可以用于管理员等的sqlite数据库,也可以是旧数据库。我使用了inspectdb为遗留数据库(的一部分)创建了一个模型,它有managed = False。但有没有办法在模型中指定它只适用于特定的数据库?

我看到你可以在一些查询集等中使用specify using=databasename但这对Databrowse(也可能是通用视图?)这样的东西不利。可能是Databrowse的一个短缺,你不能指定一个数据库,但它似乎是指定它的正确位置是模型...

然后我想也许答案是写一个自定义的model manager,只引用我的遗留数据库 - 但文档没有提到这样的东西。

对于Django世界,我是否只有一个不同的心理模型可以使用多个数据库?

django django-models multiple-databases django-database
3个回答
12
投票

据我所知,您无法直接使用模型指定数据库,因为它会阻止应用程序重复使用,但是我可以在文档中看到:

https://docs.djangoproject.com/en/1.8/topics/db/multi-db/


14
投票

您不能为模型指定数据库,但可以在自定义数据库路由器类中定义它。

# app/models.py
class SomeModel(models.Model):
    ...

# app/dbrouters.py
from app.models import SomeModel
...
class MyDBRouter(object):

    def db_for_read(self, model, **hints):
        """ reading SomeModel from otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None

    def db_for_write(self, model, **hints):
        """ writing SomeModel to otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None


# app/settings.py
DATABASE_ROUTERS = ('app.dbrouters.MyDBRouter',)
...
DATABASES = {
    ...
    'otherdb': {
        ....
    }
}

0
投票

我发现你可以使用这个管理器简单地路由模型:

class SecondDbManager(models.Manager):
    def get_queryset(self):
        qs = super().get_queryset()

        # if `use_db` is set on model use that for choosing the DB
        if hasattr(self.model, 'use_db'):
            qs = qs.using(self.model.use_db)

        return qs

只需将use_db='databasename'和此经理添加到您的模型中即可。

或者为了进一步简化它,我为它创建了一个基本模型:

class SecondDbBase(models.Model):
    use_db = 'my_second_db'

    objects = SecureDbManager()

    class Meta:
        abstract = True

有了这一切,你需要做的就是像这样扩展它。代替:

class Customer(models.Model):

只要这样做,它的工作原理:

class Customer(SecondDbBase):

PS。我不确定这是一个好的做法还是最好的解决方案,但它的工作原理和路由到其他数据库是一件轻而易举的事:)

PSS。我只使用这些只用于读写不是由Django(managed = False)管理的表,所以如果你需要为它们创建迁移,我不确定它是否有效。可能还需要使用DATABASE_ROUTERS

© www.soinside.com 2019 - 2024. All rights reserved.