日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
使用django怎么實(shí)現(xiàn)多數(shù)據(jù)庫(kù)-創(chuàng)新互聯(lián)

使用django怎么實(shí)現(xiàn)多數(shù)據(jù)庫(kù)?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司專業(yè)提供德陽(yáng)服務(wù)器托管服務(wù),為用戶提供五星數(shù)據(jù)中心、電信、雙線接入解決方案,用戶可自行在線購(gòu)買德陽(yáng)服務(wù)器托管服務(wù),并享受7*24小時(shí)金牌售后服務(wù)。

定義及路由機(jī)制

定義

在settings里面的DATABASES是一個(gè)字典,用于定義需要的數(shù)據(jù)庫(kù),如下,一共定義了兩個(gè)數(shù)據(jù)庫(kù)。

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'
 }
}

那么什么時(shí)候調(diào)用default什么時(shí)候調(diào)用users數(shù)據(jù)庫(kù)呢,這就需要下面的路由。

路由注冊(cè)

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 == 'auth3':
  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 == 'auth3':
  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 == 'auth3'
 elif model._meta.app_label == 'user2':
  return False
 return None

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

如何注冊(cè)路由

光定義路由程序無(wú)法調(diào)用到,還需要注冊(cè)到django中,在settings中定義

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

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

路由機(jī)制

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

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

2. 同樣驗(yàn)證User2Router,如果User2Router返回了非空字符串,則使用User2Router;如果不是則使用default數(shù)據(jù)庫(kù);

3. 所以可以看出,路由注冊(cè)的順序是會(huì)影響最后的結(jié)果的,注冊(cè)在前面的路由會(huì)優(yōu)先被使用;

自動(dòng)路由和手動(dòng)路由

上面定義的Router是自動(dòng)路由,意思是django會(huì)自動(dòng)輪詢所注冊(cè)的路由器,某個(gè)model會(huì)保存在哪個(gè)數(shù)據(jù)庫(kù),是django通過(guò)注冊(cè)的Router自動(dòng)獲得的,在編碼中你不需要指定;

手動(dòng)路由,則是你可以在編碼中指定某個(gè)model要保存到哪個(gè)數(shù)據(jù)庫(kù)。

而且手動(dòng)路由也有性能方面的優(yōu)點(diǎn),如果定義了很多個(gè)數(shù)據(jù)庫(kù),每次保存或者讀取model都要把輪詢一遍路由列表,顯然效率有些低,如果程序邏輯清楚的知道當(dāng)前的代碼應(yīng)該連接哪個(gè)數(shù)據(jù)庫(kù),顯示指定的方式顯然效率更高。

手動(dòng)路由

查詢

使用using函數(shù),參數(shù)就是要查詢的數(shù)據(jù)庫(kù)

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

保存或者更新

使用save的using參數(shù),值就是要使用的數(shù)據(jù)庫(kù)

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

刪除

使用delete的using參數(shù)

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

分庫(kù)技術(shù)

下面緊緊介紹分庫(kù)的思路。

垂直分庫(kù)

即一個(gè)app對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù),上面自動(dòng)路由的例子就是一個(gè)垂直分庫(kù)的例子,auth2使用user1數(shù)據(jù)庫(kù),auth3使用user2數(shù)據(jù)庫(kù)。當(dāng)然也可以使用手動(dòng)路由。

水平分庫(kù)

水平分庫(kù)建議使用手動(dòng)路由,因?yàn)槊總€(gè)model的分庫(kù)機(jī)制可能都不一樣,自動(dòng)路由實(shí)現(xiàn)起來(lái)有些麻煩會(huì)造成性能不高,而手動(dòng)路由,每個(gè)model根據(jù)自己的規(guī)則來(lái)獲得不同的數(shù)據(jù)庫(kù)。

補(bǔ)充知識(shí):Django實(shí)現(xiàn)數(shù)據(jù)庫(kù)讀寫分離、一主多從、分庫(kù)

讀寫分離

在工程中,通常需要實(shí)現(xiàn)mysql讀寫分離。在Django中需要支持讀寫分離的話,只需要很簡(jiǎn)單的幾步就可以了。

首先,配置讀庫(kù)和寫庫(kù)。

在django項(xiàng)目的settings.py中,配置讀庫(kù)和寫庫(kù)。

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': '',   
 },
}

接下來(lái),需要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)的路由分發(fā)類。

可以在appname/utils下創(chuàng)建一個(gè)db_router.py文件,在文件中定義db_router類。類中實(shí)現(xiàn)讀庫(kù)寫庫(kù)的選擇。

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' ]

重新啟動(dòng)Django就完成了。

這里需要注意的是,Django只完成了讀寫分離,但mysql主庫(kù)、從庫(kù)的同步操作并不歸django負(fù)責(zé),依然需要mysql實(shí)現(xiàn)。

一主多從

一主多從的方案在實(shí)際應(yīng)用中是更常見(jiàn)的配置。在上面配置的基礎(chǔ)上,只需要修改幾個(gè)地方,就可以實(shí)現(xiàn)一主多從了。

首先,修改settings.py,增加全部從庫(kù)的設(shè)置。

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

class DBRouter(object):
 def db_for_read(self, model, **hints):
 import random
 return random.choice(['slave', 'slave2', 'slave3'])

分庫(kù)

當(dāng)需要不同的app使用不同的庫(kù)時(shí),可以利用model中的app_label來(lái)實(shí)現(xiàn)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"

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


標(biāo)題名稱:使用django怎么實(shí)現(xiàn)多數(shù)據(jù)庫(kù)-創(chuàng)新互聯(lián)
新聞來(lái)源:http://www.dlmjj.cn/article/gejed.html