我想将我的应用程序连接到3个不同的数据库。
为此,我在设置文件中更改了以下代码:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'local_db',
'USER': 'root',
'PASSWORD': 'password1',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS': { 'sql_mode': 'traditional', }
},
'firstExternalDb': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'firstExternalDb',
'USER': 'userName',
'PASSWORD': 'password1',
'HOST': 'firstExternalDb.node.com',
'PORT': '3306',
'OPTIONS': { 'sql_mode': 'traditional', }
},
'secondExternalDb': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'secondExternalDb',
'USER': 'userName',
'PASSWORD': 'password1',
'HOST': 'secondExternalDb.node.com',
'PORT': '3306',
'OPTIONS': { 'sql_mode': 'traditional', }
},
}
我想有可能指定我将创建数据表的数据库。例如所有django表,如'auth_group','django_admin_log',我想保存在localhost中。
正在尝试创建一个完成本教程https://docs.djangoproject.com/pl/1.11/topics/db/multi-db/#topics-db-multi-db-routing
的路由器但我不明白这一点。你能否回答我的问题:
我在两个模型文件中创建了两个路由器: 第一个仅用于默认DB:
class defaultRouter:
def db_for_read(self, model, **hints):
return 'default'
def db_for_write(self, model, **hints):
return 'default'
def allow_relation(self, obj1, obj2, **hints):
db_list = ('default')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True
第二个应用程序内的第二个:
class secondExternalDbRouter:
def db_for_read(self, model, **hints):
return 'secondExternalDb'
def db_for_write(self, model, **hints):
return 'secondExternalDb'
def allow_relation(self, obj1, obj2, **hints):
db_list = ('secondExternalDb')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True
两个路由器都在模型类的正下方,在同一个文件中。
设置文件:
DATABASE_ROUTERS = [ 'mainApp.models.defaultRouter', 'secondApp.models.secondExternalDbRouter',]
答案 0 :(得分:0)
您不必为每个应用程序创建新的路由器。如果使代码更加模块化,你可能想要这样做,即你可以将路由器与其他代码保持在一起,但我个人最初不会这样做。
如果您没有为表指定读取或写入映射,则将使用默认数据库。换句话说,您只需要为不使用默认数据库的任何案例创建路由逻辑。例如,这会强制表只读,但不会影响其他任何内容:
class MyCustomRouter(object):
def db_for_write(self, model, **hints):
if model == MyReadOnlyModel:
raise Exception("This model is read only. Shame!")
return None
有关更多示例,请参阅 Django - how to specify a database for a model?。
答案 1 :(得分:0)
默认路由器
class DefaultDBRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Reads go to a default.
"""
return "default"
def db_for_write(self, model, **hints):
"""
Writes always go to default.
"""
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the default.
"""
db_list = ('default')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None
def allow_migrate(self, db, app_label, model=None, **hints):
"""
All non-micro-management models end up in this pool.
"""
return True
<强> FirstExternalDBRouter 强>
FIRST_EXTERNAL_APPS = [
# DEFINE APPS TO USE THIS DB
]
class FirstExternalDBRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label in FIRST_EXTERNAL_APPS:
return 'firstExternalDb'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in FIRST_EXTERNAL_APPS:
return 'firstExternalDb'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label in FIRST_EXTERNAL_APPS or \
obj2._meta.app_label in FIRST_EXTERNAL_APPS:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in FIRST_EXTERNAL_APPS:
return db == 'firstExternalDb'
return None
<强> SecondExternalDBRouter 强>
SECOND_EXTERNAL_APPS = [
# DEFINE APPS TO USE THIS DB
]
class SecondExternalDBRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label in SECOND_EXTERNAL_APPS:
return 'secondExternalDb'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in SECOND_EXTERNAL_APPS:
return 'secondExternalDb'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label in SECOND_EXTERNAL_APPS or \
obj2._meta.app_label in SECOND_EXTERNAL_APPS:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in SECOND_EXTERNAL_APPS:
return db == 'secondExternalDb'
return None
在参数 DATABASE_ROUTERS
中的设置中定义所有三个路由器所有三个数据库都将具有相同的模式迁移(表),只有您将控制在访问模型时要读取和写入的数据库。