我的django应用程序将连接3个不同应用程序(产品,制造商,资金)的3个不同数据库(默认为SQLite,PostgreSQL为产品和制造商数据库,MSSQL为基金数据库)
我在每个应用程序的routers.py
(productdbrouter
,manufacturerdbrouter
,fundsdbrouter
)文件中创建了3个路由器,以根据app_lable名称执行读取,写入操作。
在我的项目设置文件中,我创建了DATABASE_ROUTERS
配置,如下:
DATABASE_ROUTERS = [
"product.routers.productdbrouter","manufacturer.routers.manufacturerdbrouter", "funds.routers.fundsdbrouter",
]
现在,当我尝试访问应用程序时,它总是尝试从数据库配置中的第一个路由器查找表(在这种情况下为product.routers.productdbrouter
),如果该表丢失了,它将尝试从默认值中获取路由器(SQLite)。
我期望的是路由器,它映射到产品/制造商/基金数据库,具体取决于我尝试获取的模型。
高度推荐有关配置中缺少Iam的建议?
顺便说一句,我使用Django = 2.2.4
代码
products \ router.py
class productdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'product':
return 'productdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'product' and obj2._meta.app_label == 'product':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='product':
return db=='productdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'productdb' or model._meta.app_label == "product":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
manufacturer \ router.py
class manufacturerdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'manufacturer':
return 'manufacturerdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'manufacturer' and obj2._meta.app_label == 'manufacturer':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='manufacturer':
return db=='manufacturerdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'manufacturerdb' or model._meta.app_label == "manufacturer":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
funds \ router.py
class fundsdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'funds':
return 'fundsdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'funds':
return 'fundsdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'funds' and obj2._meta.app_label == 'funds':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='funds':
return db=='fundsdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'fundsdb' or model._meta.app_label == "funds":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
注意:由于我没有从Django应用程序中推送任何值,因此我将allow_syncdb = false设置为。该应用程序中所做的所有更改都将通过其他应用程序进行。
感谢您的帮助
答案 0 :(得分:0)
我认为问题在于您返回的建议是代码return 'default'
,而不是使用return None
。请参阅此处的文档:
https://docs.djangoproject.com/en/2.2/topics/db/multi-db/#database-routers
您还可以在整个项目中使用单个路由器,就像这样:
class MyRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def allow_relation(self, obj1, obj2, **hints):
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in (
'productdb',
'manufacturerdb',
):
return False
return True
我们正在做的是将您创建的每个Django应用的读写路由到适当的数据库(在Django的设置中,DATABASES
中定义),或者返回None
,这将使用您设置中的默认SQLite数据库。我们还告诉Django不要针对PostgreSQL或MSSQL创建任何迁移,因为我猜您不想让Django处理这些数据库的结构。
但是,这里我们不考虑allow_relation
;您可以自行决定是否跨数据库边界设置任何关系。例如,您无法从SQLite到PostgreSQL设置ForeignKey
。祝你好运!