Summary of Django multi database configuration and use

Time:2021-5-1

Summary of Django multi database configuration and use

 

By: give customer QQ: 103355122

 

#Practice environment

Win 10

 

Python 3.5.4

 

Django-2.0.13.tar.gz

Official download address:

https://www.djangoproject.com/download/2.0.13/tarball/

 

#Requirement description

In the project development, the realization of some business functions needs cross database query, and we want to realize it through Django’s own orm

 

#Solutions

To configure multiple databases for Django, the specific steps are as follows:

 

1. Modify project settings.py databases configuration

Open settings.py, modify the databases configuration – add a new configuration for the database to be connected (in this case, take the MySQL database configuration as an example, assuming that two databases need to be linked)

 

#... Brief

DATABASES = {
     #Default database configuration
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_ Name ', # custom database name
        'USER': 'db_username',
        'PASSWORD': 'db_user_password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'CONN_MAX_AGE': 30,
        'OPTION': {
            'init_command': 'SET default_storage_engine=INNODB'
        }
    },
    'seconddb ': {# seconddb represents the configuration of the second database # the name can be customized
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'second_db_name', 
        'USER': 'db_username ',
        'PASSWORD': 'db_user_password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'CONN_MAX_AGE': 30,
        'OPTION': {
            'init_command': 'SET default_storage_engine=INNODB'
        },
    },
#... Brief
}

  

For the convenience of describing the following contents, the above default and seconddb are referred to as “database configuration node” for the time being

 

2. Modify item settings.py database_ Routers routing configuration

 

Open settings.py and modify database_ Routes configuration (if it does not exist, add the configuration item)

 

DATABASES = {

#… Brief

}

 

DATABASE_ROUTERS = [‘Package.database_routers.DatabaseRouters’]

 

explain:

Package: the package where the routing rule file is located (usually the package directory with the same name as the project under the root directory of the project, or the app root directory (package directory))

 

database_ Routers: the. Py file name that defines the routing rules. The file name can be customized

 

Databaserouters: in. Py above, define the class name of routing rules, which can be customized

 

DATABASE_ Routes is a list, so multiple different routes can be configured

 

3. Establish the mapping relationship between app application and database

Add the mapping relationship between app and database in settings.py (if not), that is, configure the database to which the specified app needs to connect

 

APP_ DATABASE_ Mapping = {# mapping configuration name, customizable

‘mysite ‘:’defualt’, # format description ‘app name’:’Database configuration node ‘# note that the “app name” here must be in settings.installed_ The “database configuration node” has been registered in apps and should correspond to settings.database, neither of which can be customized

‘myblog’: ‘secondDb’,

}

 

4. Configure the app that is not allowed to perform the migration operation (to be exact, the model of the app)

APPS_ NOT_ ALLOW_ Migrate = [‘myblog ‘] # the model with app label as myblog is not allowed to be migrated

 

 

5. Create database routing rules

Create a routing rule. Py file (for example, database) in the root directory of the project and the directory with the same name as the project (in the same directory as the settings. Py file)_ routers.py )

 

Project code engineering structure directory is as follows

TMP

|–TMP

    |–settings.py

    |–database_routers.py

|–manage.py

|–… Brief

|–mysite

|–myblog

 

database_ Routers.py is as follows:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-


'''
@Author :shouke
'''

from django.conf import settings

DATABASE_MAPPING = settings.APP_DATABASE_MAPPING

DATABASES_NOT_ALLOW_MIGRATE = settings.APPS_NOT_ALLOW_MIGRATE


class DatabaseRouters(object):
    def db_for_read(self, model, **hints):
        "" specifies the database that mode should use for the read operation. If none is returned, the default database will be used“

        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None


    def db_for_write(self, model, **hints):
        "Specify the database that mode should use for write operation. If none is returned, the default database will be used."

        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None


    def allow_relation(self, obj1, obj2, **hints):
        Control whether obji1 and obji2 are allowed to establish association relationship for foreign keys and many to many operations. If true is returned, it means that it is allowed. If false is returned, it prevents the establishment of association relationship. If none is returned, it means that only objects in the same database are allowed to establish association relationship. (Note: in my personal test, execute save() to save the object containing the associated foreign key, Or get the associated foreign key object through an object, the function will not be executed     
        """

        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
         return None


    def allow_migrate(self, db, app_label, model=None, **hints):
        Specifies whether migration operations are allowed to run on a database with the alias dB. Returns true if it is allowed to run; Otherwise, return false, none“

        if app_labelin DATABASES_NOT_ALLOW_MIGRATE:
            return False
        else:
            return True

  

 

6. Create mode table

In the corresponding app, create the models of the corresponding data table. However, it should be noted that you need to consider whether to specify an app for the model according to the above routing rules and actual needs_ Label. If it is not specified, the related operations are performed on the default database.

 

The following is the sample data table mode

class BugType(models.Model):
    id = models.AutoField(primary_ key=True, verbose_ Name ='auto increment ID ')
    bug_ type = models.CharField(max_ length=50, verbose_ Name = (bug type ')

    class Meta:
        db_table = 'tb_bug_type'
        app_label = 'mysite'
        verbose_ Name ='bug type table '
        verbose_name_plural = verbose_name

class SprintBug(models.Model):
    id = models.AutoField(primary_ key=True, verbose_ Name ='auto increment ID ')
    name = models.CharField(max_ length=10, verbose_ Name = bug name ')
    but_type_id = models.IntegerField()

    class Meta:
        db_table = 'tb_sprint_bug'
        app_label = 'myblog'
        verbose_ Name ='iterate bug table '
        verbose_name_plural = verbose_name

  

 

 

explain:

Assume that the corresponding data table of the sprintbug model is an existing data table that needs to be queried across databases in the project. Therefore, when you want to perform the migrate operation in the current project, you will not create or modify its data table, which is only for ORM operation. To achieve this goal, you need to display the specified dB_ Table is the name of the table in the database, and displays the specified app_ Label value, and ensure that the app_ The above settings.apps exist in the label value_ NOT_ ALLOW_ In the migrate list (according to the above routing rules, app_ The label value exists in settings.apps_ NOT_ ALLOW_ The mode in the migrate list does not allow the migration operation).

 

7. Perform database migration

If the migration operation has not been performed, it is necessary to perform the migration operation first in order to create and modify the database table corresponding to the model

python manage.py makemigrationsappName

python manage.pymigrate

 

 

explain:

If you want to perform the migrations operation of the corresponding app and model in the specified database, you need to use the — database option. Otherwise, no app is specified_ The data table corresponding to the model of label will be executed in the default database.

 

Example: the database migration operation of MySite is executed in the database represented by myappdb1.

python manage.py makemigrationsmysite

Python manage. Py — database = myappdb1 # – note that the – database option value is actually the “database configuration node” of the target database in settings. Py, and the option value cannot be quoted or double quoted, otherwise an error will be reported

 

In this way, all other operations such as creation, query and deletion will be the same as ordinary operations, and there is no need to use similar operations

Models. User. Objects. Using (dbname). All().

   

#Reference link

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