django 配置 多數據庫


django多數據庫

閱讀spider platform時發現前端項目中使用了多數據庫,那么django實現多數據庫需要哪些配置呢,又如何使用呢?

定義及路由機制

定義

settings里面的DATABASES是一個字典,用於定義需要的數據庫,如下,一共定義了兩個數據庫。

 

DATABASES = {

    'default': {

        'NAME': 'app_data',

        'ENGINE': 'django.db.backends.postgresql_psycopg2',

        'USER': 'postgres_user',

        'PASSWORD': 's3krit'

    },

    'user1': {

        'NAME': 'user1_data',

        'ENGINE': 'django.db.backends.mysql',

        'USER': 'mysql_user',

        'PASSWORD': 'priv4te'

    }

 'user2': {

        'NAME': 'user2_data',

        'ENGINE': 'django.db.backends.mysql',

        'USER': 'mysql_user',

        'PASSWORD': 'priv4te'

    }

}

那么什么時候調用default什么時候調用users數據庫呢,這就需要下面的路由。

 

路由注冊

 

class User1Router(object):

    """ A router to control all database operations on models in the auth application. """

    def db_for_read(self, model, **hints):

        """ Attempts to read auth models go to auth_db. """

        if model._meta.app_label == 'auth':

            return 'user1'

        return None

 

    def db_for_write(self, model, **hints):

        """ Attempts to write auth models go to auth_db. """

        if model._meta.app_label == 'auth':

            return 'user1'

        return None

 

    def allow_relation(self, obj1, obj2, **hints):

        """ Allow relations if a model in the auth app is involved. """

        if obj1._meta.app_label == 'auth' or \

           obj2._meta.app_label == 'auth':

           return True

        return None

 

    def allow_syncdb(self, db, model):

        """ Make sure the auth app only appears in the 'auth_db' database. """

        if db == 'auth_db':

            return model._meta.app_label == 'auth'

        elif model._meta.app_label == 'user1':

            return False

        return None

 

 

 

 class User2Router(object):

    """ A router to control all database operations on models in the auth application. """

    def db_for_read(self, model, **hints):

        """ Attempts to read auth models go to auth_db. """

        if model._meta.app_label == 'auth2':

            return 'user2'

        return None

 

    def db_for_write(self, model, **hints):

        """ Attempts to write auth models go to auth_db. """

        if model._meta.app_label == 'auth2':

            return 'user2'

        return None

 

    def allow_relation(self, obj1, obj2, **hints):

        """ Allow relations if a model in the auth app is involved. """

        if obj1._meta.app_label == 'auth' or \

           obj2._meta.app_label == 'auth':

           return True

        return None

 

    def allow_syncdb(self, db, model):

        """ Make sure the auth app only appears in the 'auth_db' database. """

        if db == 'auth_db':

            return model._meta.app_label == 'auth2'

        elif model._meta.app_label == 'user2':

            return False

        return None

 

User1Router的路由邏輯是,如果model所屬的app是auth的話,就使用user1數據庫,否則就使用其他的;User2Router的邏輯類似。

如何注冊路由

光定義路由程序無法調用到,還需要注冊到django中,在settings中定義

DATABASE_ROUTERS = ['path.to.User1Router' , 'path.to.User2Router']

path.to:是User1Router的完整python包路徑,所以,User1Router不一定要在settings中實現,可以在任何地方。

路由機制

那么django是如何選擇其中一個路由的呢?

1. django按照注冊的順序輪詢DATABASE_ROUTERS,所以首先驗證User1Router是否返回了非空字符串,如果是,則使用User1Router;如果不是則接着驗證后面的Router;

2. 同樣驗證User2Router,如果User2Router返回了非空字符串,則使用User2Router;如果不是則使用default數據庫;

3. 所以可以看出,路由注冊的順序是會影響最后的結果的,注冊在前面的路由會優先被使用;

自動路由和手動路由

上面定義的Router是自動路由,意思是django會自動輪詢所注冊的路由器,某個model會保存在哪個數據庫,是django通過注冊的Router自動獲得的,在編碼中你不需要指定;

手動路由,則是你可以在編碼中指定某個model要保存到哪個數據庫。

而且手動路由也有性能方面的優點,如果定義了很多個數據庫,每次保存或者讀取model都要把輪詢一遍路由列表,顯然效率有些低,如果程序邏輯清楚的知道當前的代碼應該連接哪個數據庫,顯示指定的方式顯然效率更高。

手動路由

查詢

使用using函數,參數就是要查詢的數據庫

 

User.objects.using('user1').all()

保存或者更新

使用save的using參數,值就是要使用的數據庫

 

 

>>> my_object.save(using='user1')

刪除

使用delete的using參數

>>> user_obj.delete(using='user1')

 

分庫技術

下面緊緊介紹分庫的思路。

垂直分庫

即一個app對應一個數據庫,上面自動路由的例子就是一個垂直分庫的例子,auth1使用user1數據庫,auth2使用user2數據庫。當然也可以使用手動路由。

水平分庫

水平分庫建議使用手動路由,因為每個model的分庫機制可能都不一樣,自動路由實現起來有些麻煩會造成性能不高,而手動路由,每個model根據自己的規則來獲得不同的數據庫。


免責聲明!

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



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