Django 多資料庫配置與使用總結
By:授客 QQ:103355122
#實踐環境
Win 10
Python 3.5.4
Django-2.0.13.tar.gz
官方下載地址:
https://www.djangoproject.com/download/2.0.13/tarball/
#需求描述
專案開發中,部分業務功能的實作,需要跨資料庫查詢,并且想通過Django自帶ORM來實作
#解決方案
為Django配置多資料庫,具體操作步驟如下:
1、修改專案settings.py DATABASES配置
打開settings.py ,修改DATABASES配置—-為需要連接的資料庫新增配置(本例中以mysql資料庫配置為例,假設需要鏈接兩個資料庫)
# ...略
DATABASES = {
# 默認資料庫配置
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'database_name', # 自定義資料庫名稱
'USER': 'db_username',
'PASSWORD': 'db_user_password',
'HOST': '127.0.0.1',
'PORT': '3306',
'CONN_MAX_AGE': 30,
'OPTION': {
'init_command': 'SET default_storage_engine=INNODB'
}
},
'secondDb': { #secondDb代表第二個資料庫的配置#該名稱可自定義
'ENGINE': 'django.db.backends.mysql',
'NAME': 'second_db_name',
'USER': 'db_username ',
'PASSWORD': 'db_user_password',
'HOST': '127.0.0.1',
'PORT': '3306',
'CONN_MAX_AGE': 30,
'OPTION': {
'init_command': 'SET default_storage_engine=INNODB'
},
},
#...略
}
為了方便描述下文內容,這里暫且把上述的 default,secondDb等稱為“資料庫配置結點”
2、修改專案settings.py DATABASE_ROUTERS路由配置
打開settings.py ,修改DATABASE_ROUTERS配置(如果不存在,則新增該配置項)
DATABASES = {
#...略
}
DATABASE_ROUTERS = ['Package.database_routers.DatabaseRouters']
說明:
Package: 路由規則檔案所在包(一般是專案根目錄下,與專案同名的包目錄,或者app根目錄(包目錄))
database_routers: 定義路由規則的.py檔案名稱,該檔案名稱可以自定義
DatabaseRouters:上述.py中,定義路由規則的類名稱,該類名可自定義
DATABASE_ROUTERS為串列,所以,可以配置多個不同的路由
3、建立app應用和資料庫的映射關系
在settings.py中新增app和資料庫的映射關系(如果沒有的話),即針對指定app,配置其需要連接的資料庫
APP_DATABASE_MAPPING = { # 映射配置名稱,可自定義
'mysite': ' defualt', # 格式說明 'app名稱':'資料庫配置結點' # 注意,這里的“app名稱”,必須在settings.INSTALLED_APPS中已注冊,“資料庫配置結點”要同 settings.DATABASE 保持對應,兩者皆不能隨便自定義
'myblog': 'secondDb',
}
4、配置不允許執行migration操作的app(確切的說是app的model)
APPS_NOT_ALLOW_MIGRATE = ['myblog'] # 配置 app-label 為 myblog 的 model 不允許執行migration操作
5、創建資料庫路由規則
在專案根目錄下,與專案同名的目錄下(與 settings.py 檔案位于同一目錄)創建路由規則.py檔案(例中為 database_routers.py )
專案代碼工程結構目錄如下
TMP
|--TMP
|--settings.py
|--database_routers.py
|--manage.py
|--...略
|--mysite
|--myblog
database_routers.py內容如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
@Author :shouke
'''
from django.conf import settings
DATABASE_MAPPING = settings.APP_DATABASE_MAPPING
DATABASES_NOT_ALLOW_MIGRATE = settings.APPS_NOT_ALLOW_MIGRATE
class DatabaseRouters(object):
def db_for_read(self, model, **hints):
""""指定mode進行讀取操作時應使用的資料庫, 如果回傳None則表示使用默認資料庫"""
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def db_for_write(self, model, **hints):
"""指定mode進行寫入操作時應使用的資料庫, 如果回傳None則表示使用默認資料庫"""
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None
def allow_relation(self, obj1, obj2, **hints):
"""控制是否允許obj1和obj2建立關聯關系,供外鍵和多對多操作使用,如果回傳True則表示允許,如果回傳False則阻止建立關聯關系,如果回傳None則表示僅允許在相同資料庫內的物件建立關聯關系(備注:筆者親測,執行save()保存包含關聯外鍵物件,或者通過某個物件獲取關聯外鍵物件,該函式都不會被執行
"""
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_migrate(self, db, app_label, model=None, **hints):
"""指定是否允許在別名為db的資料庫上運行遷移操作,如果允許運行,則回傳True;否則回傳False、None"""
if app_labelin DATABASES_NOT_ALLOW_MIGRATE:
return False
else:
return True
6、創建mode表
在對應app中,創建對應資料表的models,不過,需要注意的是,需要根據上述路由規則,及實際需求,考慮是否為model指定app_label,如果不指定,在默認資料庫上執行相關操作,
以下為樣例資料表 mode
class BugType(models.Model):
id = models.AutoField(primary_key=True, verbose_name='自增id')
bug_type = models.CharField(max_length=50, verbose_name='bug型別')
class Meta:
db_table = 'tb_bug_type'
app_label = 'mysite'
verbose_name = 'bug型別表'
verbose_name_plural = verbose_name
class SprintBug(models.Model):
id = models.AutoField(primary_key=True, verbose_name='自增id')
name = models.CharField(max_length=10, verbose_name='bug名稱')
but_type_id = models.IntegerField()
class Meta:
db_table = 'tb_sprint_bug'
app_label = 'myblog'
verbose_name = '迭代bug表'
verbose_name_plural = verbose_name
說明:
這里假設SprintBug Model對應資料表為專案中需要跨資料庫查詢的且已存在的資料表,所以,希望在當前專案中執行migrate操作操作時,不對它進行創建、或者修改其資料表,僅供ORM操作使用,為了達到這個目的,需要顯示指定 db_table 為該據表在資料庫中的表名,并且顯示指定app_label值,并確保該 app_label 值存在上述settings.APPS_NOT_ALLOW_MIGRATE串列中(根據上述路由規則,app_label值存在settings.APPS_NOT_ALLOW_MIGRATE串列中的mode不允許執行migration操作),
7、執行資料庫遷移操作
如果還沒執行遷移操作,需要先執行遷移操作,以便創建、修改model對應的資料庫表
python manage.py makemigrationsappName
python manage.pymigrate
說明:
如果希望執行migrate操作時,對應app對應model的migrations操作,在指定資料庫中執行,則需要使用 --database 選項,否則,沒指定app_label的model對應資料表相關操作將在默認資料庫中執行,
例子:把mysite的資料庫遷移操作放到 myAppDb1 代表的資料庫中執行,
python manage.py makemigrationsmysite
python manage.py--database=myAppDb1 # 注意,--database選項值實為settings.py中目標資料庫的“資料庫配置結點”,且該選項值不能加引號、雙引號,否則會報錯
這樣以后,其它所有的創建、查詢、洗掉等操作就和普通一樣操作就可以了,無需再使用類似
models.User.objects.using(dbname).all()這樣的方式來操作,
#參考鏈接
https://docs.djangoproject.com/en/2.1/topics/db/multi-db/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/234656.html
標籤:其他
