日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

django写mysql轮询_django 多数据库及分库实现方式

發布時間:2023/12/2 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django写mysql轮询_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根據自己的規則來獲得不同的數據庫。

補充知識:Django實現數據庫讀寫分離、一主多從、分庫

讀寫分離

在工程中,通常需要實現mysql讀寫分離。在Django中需要支持讀寫分離的話,只需要很簡單的幾步就可以了。

首先,配置讀庫和寫庫。

在django項目的settings.py中,配置讀庫和寫庫。

DATABASES = {

'default': {

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

'NAME': 'WIPS',

'USER': 'mysql',

'PASSWORD': '360tianxun#^)Sec',

'HOST': '',

'PORT': '',

},

'slave': {

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

'NAME': 'TEST',

'USER': 'mysql',

'PASSWORD': '360tianxun#^)Sec',

'HOST': '',

'PORT': '',

},

}

接下來,需要創建數據庫的路由分發類。

可以在appname/utils下創建一個db_router.py文件,在文件中定義db_router類。類中實現讀庫寫庫的選擇。

class DBRouter(object):

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

return "slave"

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

return "default"

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

return True

最后,在settings.py中添加路由配置。

DATABASE_ROUTERS = ['appname.utils.db_router.DBRouter' ]

重新啟動Django就完成了。

這里需要注意的是,Django只完成了讀寫分離,但mysql主庫、從庫的同步操作并不歸django負責,依然需要mysql實現。

一主多從

一主多從的方案在實際應用中是更常見的配置。在上面配置的基礎上,只需要修改幾個地方,就可以實現一主多從了。

首先,修改settings.py,增加全部從庫的設置。

其次,修改db_router類中db_for_read(),下面是隨機選取讀庫的例子。也可以根據實際的需要,選取不同的調度算法。

class DBRouter(object):

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

import random

return random.choice(['slave', 'slave2', 'slave3'])

分庫

當需要不同的app使用不同的庫時,可以利用model中的app_label來實現db的路由。

class DBRouter(object):

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

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

import random

return random.choice(['app01_slave1', 'app01_slave2', 'app01_slave3'])

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

return "app02_slave"

按照上面的操作就很容易實現mysql的讀寫分離、一主多從和分庫了。但這個方法只建議用在小項目上。

以上這篇django 多數據庫及分庫實現方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持python博客。

總結

以上是生活随笔為你收集整理的django写mysql轮询_django 多数据库及分库实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。