Django:同一個app支持多個數據庫


我以我個人的Mynote工程說明,目的是要在backend這個app里面設置不同的model對應daysn和bear兩個數據庫進行操作

現在我們先簡單對一個完全新建的django工程配置一個自動在mysql生成表的這么一個東西,

 

配置setting

然后隨便寫個model

 

然后

E:\大數據\DjangoMyNote\Mynote>python manage.py makemigrations backend
Migrations for 'backend':
  backend\migrations\0001_initial.py
    - Create model test

E:\大數據\DjangoMyNote\Mynote>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, backend, contenttypes, sessions
Running migrations:
  Applying backend.0001_initial... OK

然后就創建了一個表,好,這是前提。ps,其他表先建了

 

好,從這里開始記錄一個完整的一個app對應多個數據庫的過程,綜合了n篇博客媽的沒有一篇靠譜

首先我們建立一個空的app,假設叫another

那么我們在我們的主工程的setting肯定要注冊進去,順便配置一下我們的數據庫連接

DATABASES = {
    #系統默認加載的數據庫daysn,於是這里的數據庫連接名為default
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'daysn',
        'USER':'root',
        "PASSWORD":'123456',
        "HOST":"*.*.*.*",
        "PORT":"3306",
        "CONN_MAX_AGE":7*3600,
    },
 #系統加載的數據庫第二個bear,於是這里的數據庫連接名為default
'default2': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'bear',
        'USER':'root',
        "PASSWORD":'123456',
        "HOST":"*。*。*。*",
        "PORT":"3306",
        "CONN_MAX_AGE":7*3600,
    },
}
#待會我們在主工程的目錄下新建一個DatabaseAppRouter文件,里面定義了一個DatabaseAppsRouter的class
DATABASE_ROUTERS
= ['Mynote.DatabaseAppRouter.DatabaseAppsRouter']
#兩個應用對應不同的數據庫 DATABASE_APPS_MAPPING
= { 'backend': 'default', 'another': 'default2', }

 

好,現在我們新建一個路由就像上面說的

然后下面這段代碼完全copy

# -*- coding: utf-8 -*-
from django.conf import settings
 
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
 
 
class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.
 
    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
    will fallback to the `default` database.
 
    Settings example:
 
    DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
    """
 
    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
 
    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
 
    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        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
 
    # for Django 1.4 - Django 1.6
    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database.""" 
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None
 
    # Django 1.7 - Django 1.11
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure that apps only appear in the related database.
        根據app_label的值只在相應的數據庫中創建一個表,如果刪除該def或
        不指定過濾條件,則一個Model會在每個數據庫里都創建一個表。
        """
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None

然后我們可以去寫我們的類了,因為我們的目的是要在backend這個app里面設置不同的model同時對應daysn和bear這兩個數據庫

那么測試如下,在backend的model.py里面加入這些玩意兒

from django.db import models

# Create your models here.

class test(models.Model):
    test_id = models.IntegerField()
    test_a_id = models.IntegerField()
 
 
class mt(models.Model):
    test_id = models.IntegerField()
    test_a_id = models.IntegerField()
 


class another(models.Model):
    test_id = models.IntegerField()
    test_a_id = models.IntegerField()
    class Meta:
        app_label = 'another'
 
class dsasdas(models.Model):
    test_id = models.IntegerField()
    test_a_id = models.IntegerField()
    class Meta:
        app_label = 'another'

同步數據庫要使用的是

python manage.py makemigrations

然后同步default
python manage.py migrate 

同步非default
python manage.py migrate --database==default2

這樣才會同步完兩個數據庫

好的,一個app連接多個數據庫表演完畢。

ps:我認為應該有其他方式啊。。不應該要通過新建一個沒怎么用的空app  another來搞,哪路大神知道的話希望能救下小弟。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM