[英]Django Database Routing
我在 Settings.py 中定義了 3 個數據庫,並在各自的應用程序文件夾中為兩個應用程序定義了路由器。 當我嘗試分別為應用程序運行manage.py migrate --database="app_db"
時,它只運行default
和第二個數據庫列表項。 如果我更改數據庫列表的順序,它將不會執行最后一個,而只會執行第二個。
設置.py
INSTALLED_APPS = [
# django apps
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# my apps
"cred",
"dms",
# third party apps
"rest_framework",
]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "databases/db.sqlite3",
},
"dms_db": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "databases/dms.sqlite3",
},
"cred_db": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "databases/cred.sqlite3",
},
}
DATABASE_ROUTERS = [
"dms.routers.DMSRouter",
"cred.routers.CredRouter",
]
AUTH_USER_MODEL = "cred.User"
CRED_DB_ROUTER = "cred_db"
DMS_DB_ROUTER = "dms_db"
如果我將dms_db
放在列表索引 1 中,那么它將遷移但cred_db
不會。 如果我將cred_db
放在索引 1 處,那么它將遷移但dms_db
不會。
信用路由器.py
from django.conf import settings
class CredRouter:
route_app_labels = ["auth", "cred", "contenttypes"]
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return settings.CRED_DB_ROUTER
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return settings.CRED_DB_ROUTER
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels
or obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == settings.CRED_DB_ROUTER
return False
dms.router.py
from django.conf import settings
class DMSRouter:
route_app_labels = [
"dms",
]
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels: # noqa
return settings.DMS_DB_ROUTER
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels: # noqa
return settings.DMS_DB_ROUTER
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels # noqa
or obj2._meta.app_label in self.route_app_labels # noqa
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == settings.DMS_DB_ROUTER
return False
我正在運行什么
遷移文件夾中只有initial_0001.py
。 所以我猜? 它沒有引起任何問題。 不確定。
manage.py makemigrations
manage.py migrate
manage.py migrate --database="cred_db"
manage.py migrate --database="dms_db"
所有模型都完全共享這種結構。
class Organization(models.Model):
name = models.CharField(max_length=255)
email = models.EmailField()
codename = models.CharField(max_length=254, unique=True)
...
objects = models.Manager()
class Meta:
verbose_name = _("organization")
verbose_name_plural = _("organization")
隨着項目的發展,我們將擁有更多的數據庫連接,因為我們將集成我們現有的 Django 應用程序,並且每個應用程序都已經建立了一個專用的數據庫服務器。 所以這個項目將連接到至少 8-10 個不同的數據庫。 對於很多人來說,通過移動手動遷移每個人將是一個問題。
路由器適用於所有數據庫,因此allow_migrate
和DMSRouter
都調用dms_db
中的cred_db
。 由於DMSRouter
僅允許將表遷移到僅dms
應用程序,因此您的其他應用程序表永遠不會遷移。 您需要做的是使用在allow_migrate
方法中傳遞的參數db
,如果它不是路由器正在處理的參數,則return None
而不是False
:
Cred.Router.py :
class CredRouter:
route_app_labels = ["auth", "cred", "contenttypes"]
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return settings.CRED_DB_ROUTER
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return settings.CRED_DB_ROUTER
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels
or obj2._meta.app_label in self.route_app_labels
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == settings.CRED_DB_ROUTER
else if db == settings.CRED_DB_ROUTER:
return False # Only apps in `route_app_labels` will be migrated to `cred_db`
return None # Let other routers decide
dms.router.py :
from django.conf import settings
class DMSRouter:
route_app_labels = [
"dms",
]
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels: # noqa
return settings.DMS_DB_ROUTER
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels: # noqa
return settings.DMS_DB_ROUTER
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels # noqa
or obj2._meta.app_label in self.route_app_labels # noqa
):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.route_app_labels:
return db == settings.DMS_DB_ROUTER
else if db == settings.DMS_DB_ROUTER:
return False # Only apps in `route_app_labels` will be migrated to `dms_db`
return None # Let other routers decide
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.