django配置連接多個數據庫,自定義表名稱


在項目tt下新建兩個app,分別為app01、app02。配置app01使用default節點數據庫;app02使用hvdb節點數據庫(也可以配置app01下的model既使用default,也可以使用hvdb數據庫)

1.編輯settings.py,添加多個數據庫:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testly',
        'USER': 'root',
        'PASSWORD': '123456789',
        'HOST':'192.168.1.1',
        'PORT':'3306',
    },
    'hvdb':{   #配置第二個數據庫節點名稱
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdjango', #第二個數據庫的名稱
        'USER': 'root',
        'PASSWORD': '123456789',
        'HOST':'192.168.1.1',
        'PORT':'3306',   
    }
}

Django 要求default 數據庫必須定義,但是如果不會用到,其參數字典可以保留為空。若要這樣做,你必須為你的所有的應用的模型建立DATABASE_ROUTERS,包括正在使用的contrib 中的應用和第三方應用。

default留空寫法:

'default': {},

2.添加數據庫路由表

   在tt目錄下新建文件db_router.py,內如如下。該文件用來對數據庫進行自動路由,可以根據每個model的app_label來指定使用某個DB

   注:可以定義多個Router,由於此處的app01使用default數據庫,所以在此無需指定default節點的數據庫路由。

# -*- coding: UTF-8 -*-
class app02Router(object): #配置app02的路由,去連接hvdb數據庫 """
    A router to control all database operations on models in the app02 application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read app02 models go to hvdb DB.
        """
        if model._meta.app_label == 'app02': #app name(如果該app不存在,則無法同步成功)
            return 'hvdb' #hvdb為settings中配置的database節點名稱,並非db name。dbname為testdjango
        return None
 
    def db_for_write(self, model, **hints):
        """
        Attempts to write app02 models go to hvdb DB.
        """
        if model._meta.app_label == 'app02':
            return 'hvdb'
        return None
 
    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the app02 app is involved.
        當 obj1 和 obj2 之間允許有關系時返回 True ,不允許時返回 False ,或者沒有 意見時返回 None 。
        """
        if obj1._meta.app_label == 'app02' or \
           obj2._meta.app_label == 'app02':
            return True
        return None
 
    def allow_migrate(self, db, model):
        """
        Make sure the app02 app only appears in the hvdb database.
        """
        if db == 'hvdb':
            return model._meta.app_label == 'app02'
        elif model._meta.app_label == 'app02':
            return False

 
    def allow_syncdb(self, db, model): #決定 model 是否可以和 db 為別名的數據庫同步
        if db == 'hvdb' or model._meta.app_label == "app02":
            return False  # we're not using syncdb on our hvdb database
        else:  # but all other models/databases are fine
            return True
        return None
 

# class app01Router(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 == 'app01':
#             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 == 'app01':
#             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 == 'app01' or obj2._meta.app_label == 'app01':
#             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 == 'app01'
#         elif model._meta.app_label == 'app01':
#             return False
#         return None

3.編輯settings.py,添加路由

   注:由於此處的app01使用default數據庫,所以在此無需指定default節點的數據庫路由。

DATABASE_ROUTERS = ['tt.db_router.app02Router'] #tt為當前項目名稱,db_router為上一步編寫的db_router.py文件,app02Router為Router #DATABASE_ROUTERS = ['tt.db_router.app02Router','tt.db_router.app01Router'] #如果定義了多個Router,在此就需要分別指定。注意:這個是有順序的(先匹配上的規則,就先生效)

4.為每個app的model分別指定所需要連接的數據庫

   通過對每個model指定好對應的app_label,使其通過Router去連接相應的數據庫。

  編輯app02下的models.py,為app02下的model mtable01指定連接hvdb節點數據庫,內容如下:

class mtable01(models.Model):
    name=models.CharField(max_length=100,primary_key=True,unique=True)
    ip=models.GenericIPAddressField()
    rating = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        app_label = 'app02' #定義該model的app_label
        ordering = ['name'] 使用migrate命令同步數據庫:

編輯app01下的models.py:

class tb05(models.Model): #該model使用default數據庫
    name=models.CharField(max_length=100,primary_key=True,unique=True)
    ip=models.GenericIPAddressField()
    rating = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        #app_label = 'app01' #由於該model連接default數據庫,所以在此無需指定
        ordering = ['name'] 

 也可以為app01下的model指定連接hvdb數據庫,內容如下:

class tb2(models.Model):
    name=models.CharField(max_length=100,primary_key=True,unique=True)
    ip=models.GenericIPAddressField()
    rating = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        app_label = 'app02'
        ordering = ['name'] 

為app01下的tb02指定使用hvdb數據庫,同時自定義表名稱為‘mytable’,不使用默認的表名稱app02_tb06,不便於區分

class tb06(models.Model):
    name=models.CharField(max_length=100,primary_key=True,unique=True,db_column='mycname') #使用db_column自定義字段名稱
    ip=models.GenericIPAddressField()
    rating = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'mytable' #自定義表名稱為mytable
        verbose_name = '自定義名稱' #指定在admin管理界面中顯示的名稱 
        app_label = 'app02'
        ordering = ['name'] 

 

5.同步數據庫:

 migrate管理命令一次操作一個數據庫。默認情況下,它在default 數據庫上操作,但是通過提供一個 --database 參數,告訴migrate同步一個不同的數據庫。

1)同步default節點數據庫,只運行不帶 --database參數的命令,不對其他數據庫進行同步

python manage.pymigrate
python manage.py makemigrations
python manage.pymigrate

2)同步hvdb節點數據庫:

python manage.pymigrate --database=hvdb
python manage.py makemigrations
python manage.pymigrate --database=hvdb

結果:

testdjango數據庫(hvdb節點)下的app02_mtable01表對應app02下的mtable01模型

testdjango數據庫(hvdb節點)下的app02_tb2表對應app01下的tb2模型

testly數據庫(default節點)下的app01_tb05表對應app01下的tb05模型

  參考:http://smilejay.com/2014/07/django-use-mult-databases/ 根據model的app label區分數據庫

       http://my.oschina.net/u/572994/blog/108533  根據應用自動區分數據庫

       http://python.usyiyi.cn/django/topics/db/multi-db.html  Django文檔

 


免責聲明!

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



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