在django項(xiàng)目中, 一個(gè)工程中存在多個(gè)APP應(yīng)用很常見(jiàn);有時(shí)候希望不同的APP連接不同的數(shù)據(jù)庫(kù),這個(gè)時(shí)候需要建立多個(gè)數(shù)據(jù)庫(kù)連接。
在Django的setting中使用DATABASES設(shè)置定義數(shù)據(jù)庫(kù),可以將數(shù)據(jù)庫(kù)映射到特定的別名字典中;DATABASES定義的是要給嵌套字典,該設(shè)置必須配置default默認(rèn)數(shù)據(jù)庫(kù)。默認(rèn)使用SQLite進(jìn)行單一數(shù)據(jù)庫(kù)設(shè)置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase',
}
}
如不使用默認(rèn)數(shù)據(jù)庫(kù)定義可以將默認(rèn)配置為空字典形式:
'default':{}
ATOMIC_REQUESTS:為T(mén)rue時(shí)數(shù)據(jù)庫(kù)事務(wù)包裝每個(gè)視圖,默認(rèn)為False
AUTOCOMMIT:為False時(shí)禁用Django事務(wù)管理,默認(rèn)為T(mén)rue
ENGINE:設(shè)置數(shù)據(jù)庫(kù)類型
'django.db.backends.postgresql'
'django.db.backends.mysql'
'django.db.backends.sqlite3'
'django.db.backends.oracle'
HOST:指定連接的主機(jī)名或ip地址,如果使用(‘/’)正斜杠開(kāi)頭則通過(guò)套接字連接:
'HOST':'127.0.0.1' #TCP套接字連接
'HOST':'/var/run/mysql' #UNIX套接字
NAME:制定使用的數(shù)據(jù)庫(kù)名,對(duì)于SQLite它是指定數(shù)據(jù)庫(kù)文件的路徑,在window上也要使用正斜杠。
'NAME':'databasename'
'NAME':'C:/user/mysite/sqlite3.db'
CONN_MAX_AGE:數(shù)據(jù)庫(kù)連接的生命周期,默認(rèn)為0請(qǐng)求結(jié)束時(shí)關(guān)閉數(shù)據(jù)庫(kù),設(shè)置為None無(wú)限持久連接。
OPTIONS:鏈接到數(shù)據(jù)庫(kù)時(shí)使用的額外參數(shù),可用參數(shù)因數(shù)據(jù)庫(kù)類型而異。
'OPTIONS':{'read_default_file':'path/to/my.cnf',} #優(yōu)先于NAME,USER,PASSWORD,HOST,PORT
#設(shè)置mysql啟用嚴(yán)格模式
'OPTIONS':{'init_command':"SET sql_mode='STRICT_TRANS_TABLES'"}
PASSWORD:設(shè)置密碼,不與SQLite一起使用
PORT:指定端口
TIME_ZONE:設(shè)置時(shí)區(qū)
DISABLE_SERVER_SIDE_CURSORS:True時(shí)禁用服務(wù)器端游標(biāo)
USER:鏈接用戶名
TEST:測(cè)試數(shù)據(jù)庫(kù)
#自定義兩個(gè)mysql數(shù)據(jù)庫(kù)映射到db1和db2上
'db1':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': '172.16.32.133',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}, #mysql使用嚴(yán)格模式,不指定會(huì)有警告信息
},
'db2':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db2',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': '172.16.32.133',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
如果訪問(wèn)沒(méi)有在DATABASES中定義的數(shù)據(jù)庫(kù),Django會(huì)報(bào):django.db.utils.ConnectionDoesNotExist 異常。
migrate管理命令會(huì)同時(shí)在每一個(gè)數(shù)據(jù)庫(kù)上運(yùn)行,默認(rèn)情況下它在default數(shù)據(jù)庫(kù)上運(yùn)行 ,可以通過(guò)選項(xiàng) --database來(lái)指定需要同步的數(shù)據(jù)庫(kù)。如不指定會(huì)同步到default數(shù)據(jù)庫(kù)上。
遷移同步命令:
makemigrations:根據(jù)簡(jiǎn)稱到的變化創(chuàng)建新的遷移。
migrate:將模型和遷移數(shù)據(jù)同步到數(shù)據(jù)庫(kù)中。
通過(guò)上面的列子,將每個(gè)應(yīng)用程序同步到特定的數(shù)據(jù)庫(kù):
#python manage.py migrate #同步默認(rèn)數(shù)據(jù)庫(kù)
#python manage.py migrate --database=db1
#python manage.py migrate --database=db2
多個(gè)數(shù)據(jù)庫(kù)導(dǎo)出:
python manage.py dumpdata app01 --database=db1 > app1_fixture.json
python manage.py dumpdata app02 --database=db2 > app2_fixture.json
python manage.py dumpdata auth > auth_fixture.json
多個(gè)數(shù)據(jù)庫(kù)導(dǎo)入:
python manage.py loaddata app1_fixture.json --database=db1
python manage.py loaddata app2_fixture.json --database=db2
使用多個(gè)數(shù)據(jù)庫(kù)時(shí)最簡(jiǎn)單的方法是設(shè)置數(shù)據(jù)庫(kù)路由方案,以保證對(duì)象對(duì)原始數(shù)據(jù)庫(kù)的“粘性",默認(rèn)所有的查詢都會(huì)返回到default數(shù)據(jù)庫(kù)中。
數(shù)據(jù)庫(kù)路由器是一個(gè)最多提供四種方法的類:
db_for_read(model,**hints) :應(yīng)用于讀取類型對(duì)象的數(shù)據(jù)庫(kù)模型,如果數(shù)據(jù)庫(kù)提供附加信息會(huì)在hints字典中提供,最后如果沒(méi)有則返回None
db_for_write(model,**hints):應(yīng)用于寫(xiě)入類型對(duì)象的數(shù)據(jù)庫(kù)模型,hints字典提供附加信息,如果沒(méi)有則返回None
allow_relation(obj1,obj2,**hints):外鍵操作,判斷兩個(gè)對(duì)象之間是否是應(yīng)該允許關(guān)系,是返回True,否則返回False,如果路由允許返回None
allow_migrate(db,app_label,model_name=None,**hints):db確定是否允許在具有別名的數(shù)據(jù)庫(kù)上運(yùn)行遷移操作,操作運(yùn)行返回True,否則返回False,或者返回None,如果路由器沒(méi)有意見(jiàn)。
app_label:位置參數(shù)是正在遷移的應(yīng)用程序的標(biāo)簽。
model_name:多個(gè)遷移操作設(shè)置模型的值,如:model._meta.app_label
在項(xiàng)目工程根路徑下(與 settings.py 文件一級(jí))創(chuàng)建數(shù)據(jù)庫(kù)路由表,app應(yīng)用會(huì)根據(jù)指定的路由選擇數(shù)據(jù)庫(kù):
app01,app02分別使用db1和db2數(shù)據(jù)庫(kù):
#!/usr/bin/env python
#coding:utf8
from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING #在setting中定義的路由表
class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def allow_relation(self, obj1, obj2, **hints):
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
def allow_syncdb(self, db, model):
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
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in DATABASE_MAPPING.values():
return DATABASE_MAPPING.get(app_label) == db
elif app_label in DATABASE_MAPPING:
return False
return None
在setting.py中配置DATABASE_ROUTERS指定自由路由文件:
#test_django為項(xiàng)目名,database_router為路由文件名,DatabaseAppsRouter為路由中創(chuàng)建的類名
DATABASE_ROUTERS = ['test_django.database_router.DatabaseAppsRouter']
在setting.py中DATABASE_ROUTERS下面設(shè)置app與數(shù)據(jù)庫(kù)匹配路由表,采用字典方式app名對(duì)應(yīng)數(shù)據(jù)庫(kù)映射名:
DATABASE_APPS_MAPPING = {
'app01':'db1',
'app02':'db2',
}
分別在app01和app02下創(chuàng)建model類,用于生成數(shù)據(jù)表:
app01:
from django.db import models
# Create your models here.
class ap1(models.Model):
username = models.CharField(max_length=30)
class Meta:
#app_label = 'app02' #如果指定將在app02對(duì)應(yīng)的數(shù)據(jù)庫(kù)下創(chuàng)建數(shù)據(jù)表
class ap2(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
app02:
from django.db import models
class ap3(models.Model):
app2_name = models.CharField(max_length=50)
sex = models.CharField(max_length=50)
data = models.DateField()
class ap4(models.Model):
app2 = models.CharField(max_length=50)
sex1 = models.CharField(max_length=50)
data1 = models.DateField()
class Meta:
db_table = 'mytable' #自定義表名稱
migrate管理命令一次只能操作一個(gè)數(shù)據(jù)庫(kù),默認(rèn)操作default數(shù)據(jù)庫(kù),使用--database指定同步的數(shù)據(jù)庫(kù):
#python manage.py migrate #生成表數(shù)據(jù)同步
#python manage.py makemigrations #創(chuàng)建變動(dòng)數(shù)據(jù)
#python manage.py migrate --database=db1 #同步指定數(shù)據(jù)庫(kù)
#python manage.py migrate --database=db2
需要注意:在多個(gè)app分庫(kù)時(shí),必須指定每個(gè)app對(duì)應(yīng)的數(shù)據(jù)庫(kù),否則在同步數(shù)據(jù) 庫(kù)時(shí)將沒(méi)指定的app模板都同步到同步數(shù)據(jù)庫(kù)中。
用using()指定查詢的數(shù)據(jù)庫(kù)的別名:
>>> # So will this.
>>> Author.objects.using('default').all()
>>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()
保存數(shù)據(jù),Model.save()指定將數(shù)據(jù)保存到哪個(gè)數(shù)據(jù)庫(kù)中:
>>> my_object.save(using='legacy_users')
#會(huì)將數(shù)據(jù)保存到legacy_users數(shù)據(jù)庫(kù)中,如不指定會(huì)保持到默認(rèn)數(shù)據(jù)庫(kù)中。
>>> my_object.delete(using='legacy_users')
#刪除指定數(shù)據(jù)庫(kù)
移動(dòng)對(duì)象到另一個(gè)數(shù)據(jù)庫(kù)時(shí)會(huì)發(fā)生主鍵沖突,可以使用obj.pk方法清除主鍵再保存對(duì)象。
>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
分享文章:Django使用多數(shù)據(jù)庫(kù)Forpython3-創(chuàng)新互聯(lián)
鏈接地址:http://chinadenli.net/article12/cdjegc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、做網(wǎng)站、網(wǎng)站改版、網(wǎng)站建設(shè)、企業(yè)建站、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容