Django中使用多个数据库

在Django项目中,可能需要连接2个或多个数据库。我在项目中遇到了这种需求,文末参考文档中有更多的知识点;不过,我自己使用的是编写自己的Database Router。

首先,在setting.py文件中,需要配置好多个数据库,如:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'abc',
        'USER': 'abc',
        'PASSWORD': '123456',
        'HOST': '192.168.100.100',
        'PORT': 3306,
    },
    'bugzilla': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bugzilla',
        'USER': 'def',
        'PASSWORD': '123456',
        'HOST': '192.168.100.101',
        'PORT': 3306,
    }
}

2. 编写Database Router,可以根据model的app_label来指定使用某个DB,如下(在db_router.py):

class BugzillaRouter(object):
    """
    A router to control all database operations on models in the
    bugzilla application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read bugzilla models go to bugzilla DB.
        """
        if model._meta.app_label == 'bugzilla':
            return 'bugzilla'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write bugzilla models go to bugzilla DB.
        """
        if model._meta.app_label == 'bugzilla':
            return 'bugzilla'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the bugzilla app is involved.
        """
        if obj1._meta.app_label == 'bugzilla' or \
           obj2._meta.app_label == 'bugzilla':
            return True
        return None

    def allow_migrate(self, db, model):
        """
        Make sure the bugzilla app only appears in the bugzilla database.
        """
        if db == 'bugzilla':
            return model._meta.app_label == 'bugzilla'
        elif model._meta.app_label == 'bugzilla':
            return False

    def allow_syncdb(self, db, model):
        if db == 'bugzilla' or model._meta.app_label == "bugzilla":
            return False  # we're not using syncdb on our bugzilla database
        else:  # but all other models/databases are fine
            return True
        return None


class AewRouter(object):
    """
    A router to control all database operations on models in the
    aew application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read aew models go to aew DB.
        """
        if model._meta.app_label == 'aew':
            return 'default'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write aew models go to aew DB.
        """
        if model._meta.app_label == 'aew':
            return 'default'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the aew app is involved.
        """
        if obj1._meta.app_label == 'aew' or obj2._meta.app_label == 'aew':
            return True
        return None

    def allow_migrate(self, db, model):
        """
        Make sure the aew app only appears in the aew database.
        """
        if db == 'default':
            return model._meta.app_label == 'aew'
        elif model._meta.app_label == 'aew':
            return False
        return None

3. 在settings.py文件中配置DB router,例如:
DATABASE_ROUTERS = [‘aew.db_router.BugzillaRouter’, ‘aew.db_router.AewRouter’]
注意这个是有顺序的(先匹配上的规则,就先生效)。

4. 在models中配置想用的model时,指定好app_label,如下:

class Products(models.Model):
    '''
    @note: sycn from bugzilla
    '''
    id = models.IntegerField(primary_key=True)
    name = models.CharField(unique=True, max_length=64)
    classification = models.ForeignKey(Classifications)
    isactive = models.IntegerField()

    class Meta:
        app_label = 'aew'
        db_table = 'products'


class Classifications(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(unique=True, max_length=64)
    description = models.TextField(blank=True)
    sortkey = models.IntegerField()

    class Meta:
        app_label = 'bugzilla'
        managed = False
        db_table = 'classifications'

这样配置的情况下,Products就是使用的default的DB,而Classifications就是使用的bugzilla DB.

参考资料:
https://docs.djangoproject.com/en/dev/topics/db/multi-db/
https://thenewcircle.com/s/post/1242/django_multiple_database_support

master

Stay hungry, stay foolish.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

*